Sanitizing clipboard handling
[quassel.git] / src / qtui / bufferwidget.cpp
1 /***************************************************************************
2  *   Copyright (C) 2005-08 by the Quassel Project                          *
3  *   devel@quassel-irc.org                                                 *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU General Public License as published by  *
7  *   the Free Software Foundation; either version 2 of the License, or     *
8  *   (at your option) version 3.                                           *
9  *                                                                         *
10  *   This program is distributed in the hope that it will be useful,       *
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13  *   GNU General Public License for more details.                          *
14  *                                                                         *
15  *   You should have received a copy of the GNU General Public License     *
16  *   along with this program; if not, write to the                         *
17  *   Free Software Foundation, Inc.,                                       *
18  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
19  ***************************************************************************/
20
21 #include <QLayout>
22 #include <QKeyEvent>
23 #include <QScrollBar>
24
25 #include "action.h"
26 #include "actioncollection.h"
27 #include "bufferwidget.h"
28 #include "chatview.h"
29 #include "chatviewsearchbar.h"
30 #include "chatviewsearchcontroller.h"
31 #include "client.h"
32 #include "inputline.h"
33 #include "qtui.h"
34 #include "settings.h"
35
36
37 BufferWidget::BufferWidget(QWidget *parent)
38   : AbstractBufferContainer(parent),
39     _chatViewSearchController(new ChatViewSearchController(this))
40 {
41   ui.setupUi(this);
42   layout()->setContentsMargins(0, 0, 0, 0);
43   layout()->setSpacing(0);
44   // ui.searchBar->hide();
45
46   _chatViewSearchController->setCaseSensitive(ui.searchBar->caseSensitiveBox()->isChecked());
47   _chatViewSearchController->setSearchSenders(ui.searchBar->searchSendersBox()->isChecked());
48   _chatViewSearchController->setSearchMsgs(ui.searchBar->searchMsgsBox()->isChecked());
49   _chatViewSearchController->setSearchOnlyRegularMsgs(ui.searchBar->searchOnlyRegularMsgsBox()->isChecked());
50
51   connect(ui.searchBar->searchEditLine(), SIGNAL(textChanged(const QString &)),
52           _chatViewSearchController, SLOT(setSearchString(const QString &)));
53   connect(ui.searchBar->caseSensitiveBox(), SIGNAL(toggled(bool)),
54           _chatViewSearchController, SLOT(setCaseSensitive(bool)));
55   connect(ui.searchBar->searchSendersBox(), SIGNAL(toggled(bool)),
56           _chatViewSearchController, SLOT(setSearchSenders(bool)));
57   connect(ui.searchBar->searchMsgsBox(), SIGNAL(toggled(bool)),
58           _chatViewSearchController, SLOT(setSearchMsgs(bool)));
59   connect(ui.searchBar->searchOnlyRegularMsgsBox(), SIGNAL(toggled(bool)),
60           _chatViewSearchController, SLOT(setSearchOnlyRegularMsgs(bool)));
61   connect(ui.searchBar->searchUpButton(), SIGNAL(clicked()),
62           _chatViewSearchController, SLOT(highlightPrev()));
63   connect(ui.searchBar->searchDownButton(), SIGNAL(clicked()),
64           _chatViewSearchController, SLOT(highlightNext()));
65
66   connect(_chatViewSearchController, SIGNAL(newCurrentHighlight(QGraphicsItem *)),
67           this, SLOT(scrollToHighlight(QGraphicsItem *)));
68
69   ActionCollection *coll = QtUi::actionCollection();
70
71   Action *zoomChatview = coll->add<Action>("ZoomChatView");
72   connect(zoomChatview, SIGNAL(triggered()), SLOT(zoomIn()));
73   zoomChatview->setText(tr("Enlarge Chat View"));
74   zoomChatview->setShortcut(tr("Ctrl++"));
75
76   Action *zoomOutChatview = coll->add<Action>("ZoomOutChatView");
77   connect(zoomOutChatview, SIGNAL(triggered()), SLOT(zoomOut()));
78   zoomOutChatview->setText(tr("Demagnify Chat View"));
79   zoomOutChatview->setShortcut(tr("Ctrl+-"));
80
81   Action *zoomNormalChatview = coll->add<Action>("ZoomNormalChatView");
82   connect(zoomNormalChatview, SIGNAL(triggered()), SLOT(zoomNormal()));
83   zoomNormalChatview->setText(tr("Normalize zoom of Chat View"));
84   zoomNormalChatview->setShortcut(tr("Ctrl+0"));
85 }
86
87 BufferWidget::~BufferWidget() {
88   delete _chatViewSearchController;
89   _chatViewSearchController = 0;
90 }
91
92 AbstractChatView *BufferWidget::createChatView(BufferId id) {
93   ChatView *chatView;
94   chatView = new ChatView(id, this);
95   _chatViews[id] = chatView;
96   ui.stackedWidget->addWidget(chatView);
97   chatView->setFocusProxy(this);
98   return chatView;
99 }
100
101 void BufferWidget::removeChatView(BufferId id) {
102   QWidget *view = _chatViews.value(id, 0);
103   if(!view) return;
104   ui.stackedWidget->removeWidget(view);
105   view->deleteLater();
106   _chatViews.take(id);
107 }
108
109 void BufferWidget::showChatView(BufferId id) {
110   if(!id.isValid()) {
111     ui.stackedWidget->setCurrentWidget(ui.page);
112   } else {
113     ChatView *view = qobject_cast<ChatView *>(_chatViews.value(id));
114     Q_ASSERT(view);
115     ui.stackedWidget->setCurrentWidget(view);
116     _chatViewSearchController->setScene(view->scene());
117   }
118 }
119
120 void BufferWidget::scrollToHighlight(QGraphicsItem *highlightItem) {
121   ChatView *view = qobject_cast<ChatView *>(ui.stackedWidget->currentWidget());
122   if(view) {
123     view->centerOn(highlightItem);
124   }
125 }
126
127
128 void BufferWidget::zoomIn() {
129   ChatView *view = qobject_cast<ChatView *>(ui.stackedWidget->currentWidget());
130   if(!view) return;
131   view->zoomIn();
132 }
133
134 void BufferWidget::zoomOut() {
135   ChatView *view = qobject_cast<ChatView *>(ui.stackedWidget->currentWidget());
136   if(!view) return;
137   view->zoomOut();
138 }
139
140 void BufferWidget::zoomNormal() {
141   ChatView *view = qobject_cast<ChatView *>(ui.stackedWidget->currentWidget());
142   if(!view) return;
143   view->zoomNormal();
144 }
145
146 bool BufferWidget::eventFilter(QObject *watched, QEvent *event) {
147   Q_UNUSED(watched);
148   if(event->type() != QEvent::KeyPress)
149     return false;
150
151   QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
152
153   // Intercept copy key presses
154   if(keyEvent == QKeySequence::Copy) {
155     InputLine *inputLine = qobject_cast<InputLine *>(watched);
156     if(!inputLine)
157       return false;
158     if(inputLine->hasSelectedText())
159       return false;
160     ChatView *view = qobject_cast<ChatView *>(ui.stackedWidget->currentWidget());
161     if(view)
162       view->scene()->selectionToClipboard();
163     return true;
164   }
165
166   int direction = 1;
167   switch(keyEvent->key()) {
168     case Qt::Key_PageUp:
169     case Qt::Key_PageDown:
170       // static cast to access public qobject::event
171       return static_cast<QObject*>(ui.stackedWidget->currentWidget())->event(event);
172
173     case Qt::Key_Up:
174       direction = -1;
175     case Qt::Key_Down:
176       if(keyEvent->modifiers() == Qt::ShiftModifier) {
177         QAbstractScrollArea *scrollArea = qobject_cast<QAbstractScrollArea*>(ui.stackedWidget->currentWidget());
178         if(!scrollArea)
179           return false;
180         int sliderPosition = scrollArea->verticalScrollBar()->value();
181         scrollArea->verticalScrollBar()->setValue(sliderPosition + (direction * 12));
182         return true;
183       }
184     default:
185       return false;
186   }
187 }