~ubuntu-branches/ubuntu/maverick/psi/maverick

« back to all changes in this revision

Viewing changes to src/msgmle.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Jan Niehusmann
  • Date: 2006-01-20 00:20:36 UTC
  • mfrom: (1.2.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20060120002036-7nw6yo6totip0ee5
Tags: 0.10-2
* Added upstream changelog (Closes: Bug#327748)
* Mention --no-gpg and --no-gpg-agent in manpage (Closes: Bug#204416)

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
 *
19
19
 */
20
20
 
 
21
#include<qapplication.h>
 
22
#include<qlayout.h>
 
23
#include<qtimer.h>
 
24
 
21
25
#include"common.h"
22
26
#include"msgmle.h"
23
27
 
34
38
        setReadOnly(true);
35
39
        setUndoRedoEnabled(false);
36
40
        setHScrollBarMode(QScrollView::AlwaysOff);
 
41
 
 
42
#ifndef Q_WS_X11        // linux has this feature built-in
 
43
        connect(this, SIGNAL(copyAvailable(bool)), SLOT(autoCopy(bool)));
 
44
#endif
 
45
 
37
46
}
38
47
 
39
48
ChatView::~ChatView()
57
66
                e->ignore();
58
67
        else if(e->key() == Key_H && (e->state() & ControlButton))
59
68
                e->ignore();
 
69
        else if(e->key() == Key_I && (e->state() & ControlButton))
 
70
                e->ignore();
60
71
        else if(e->key() == Key_M && (e->state() & ControlButton)) // newline
61
72
                insert("\n");
62
73
        else if(e->key() == Key_U && (e->state() & ControlButton))
74
85
        QTextEdit::resizeEvent(e);
75
86
}
76
87
 
 
88
/*!
 
89
        Copies any selected text (from selection 0) to the clipboard
 
90
        if option.autoCopy is TRUE, \a copyAvailable is TRUE
 
91
        and ChatView is in read-only mode.
 
92
        In any other case it does nothing.
 
93
 
 
94
        This slot is connected with copyAvailable(bool) signal
 
95
        in ChatView's constructor.
 
96
 
 
97
        \sa copyAvailable()
 
98
*/
 
99
 
 
100
void ChatView::autoCopy(bool copyAvailable)
 
101
{
 
102
        if ( isReadOnly() && copyAvailable && option.autoCopy ) {
 
103
                copy();
 
104
        }
 
105
}
 
106
 
77
107
//----------------------------------------------------------------------------
78
108
// ChatEdit
79
109
//----------------------------------------------------------------------------
116
146
                e->ignore();
117
147
        else if((e->key() == Key_PageUp || e->key() == Key_PageDown) && (e->state() & ShiftButton))
118
148
                e->ignore();
119
 
        else if(e->key() == Key_U && (e->state() & ControlButton))
120
 
                setText("");
 
149
        else if((e->key() == Key_PageUp || e->key() == Key_PageDown) && (e->state() & ControlButton))
 
150
                e->ignore();
121
151
        else if(e->key() == Key_C && (e->state() & ControlButton) && !hasSelectedText())
122
152
                e->ignore();
123
153
        else
124
154
                QTextEdit::keyPressEvent(e);
125
155
}
126
156
 
 
157
//----------------------------------------------------------------------------
 
158
// LineEdit
 
159
//----------------------------------------------------------------------------
 
160
LineEdit::LineEdit( QWidget *parent, const char *name )
 
161
        : ChatEdit( parent, name )
 
162
{
 
163
        lastSize = QSize( 0, 0 );
 
164
        initialWindowGeometry = QRect( 0, 0, 0, 0 );
 
165
 
 
166
        QWidget *topParent = topLevelWidget();
 
167
        topParent->installEventFilter( this );
 
168
        moveTo = QPoint(topParent->x(), topParent->y());
 
169
 
 
170
        moveTimer = new QTimer( this );
 
171
        connect( moveTimer, SIGNAL(timeout()), SLOT(checkMoved()) );
 
172
 
 
173
        // LineEdit's size hint is to be vertically as small as possible
 
174
        setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Maximum );
 
175
 
 
176
        setWrapPolicy( AtWordOrDocumentBoundary ); // no need for horizontal scrollbar with this
 
177
        setHScrollBarMode(QScrollView::AlwaysOff);
 
178
 
 
179
        setMinimumHeight(-1);
 
180
 
 
181
        connect( this, SIGNAL( textChanged() ), SLOT( recalculateSize() ) );
 
182
}
 
183
 
 
184
LineEdit::~LineEdit()
 
185
{
 
186
}
 
187
 
 
188
/*!
 
189
 * Returns true if the dialog could be automatically resized by LineEdit.
 
190
 */
 
191
bool LineEdit::allowResize() const
 
192
{
 
193
        QWidget *topParent = topLevelWidget();
 
194
 
 
195
        QRect desktop = qApp->desktop()->availableGeometry( (QWidget *)topParent );
 
196
        float desktopArea = desktop.width() * desktop.height();
 
197
        float dialogArea  = topParent->frameGeometry().width() * topParent->frameGeometry().height();
 
198
 
 
199
        // maximized and large chat windows shoulnd't resize the dialog
 
200
        if ( (dialogArea / desktopArea) > 0.9 )
 
201
                return false;
 
202
 
 
203
        return true;
 
204
}
 
205
 
 
206
/*!
 
207
 * In this implementation, it is quivalent to sizeHint().
 
208
 */
 
209
QSize LineEdit::minimumSizeHint() const
 
210
{
 
211
        return sizeHint();
 
212
}
 
213
 
 
214
/*!
 
215
 * All magic is contained within this function. It determines the possible maximum
 
216
 * height, and controls the appearance of vertical scrollbar.
 
217
 */
 
218
QSize LineEdit::sizeHint() const
 
219
{
 
220
        if ( lastSize.width() != 0 && lastSize.height() != 0 )
 
221
                return lastSize;
 
222
 
 
223
        lastSize.setWidth( QTextEdit::sizeHint().width() );
 
224
        int h = 7;
 
225
 
 
226
        if ( paragraphs() > 0 ) {
 
227
                for ( int i = 0; i < paragraphs(); i++ ) {
 
228
                        h += paragraphRect( i ).height();
 
229
                }
 
230
        }
 
231
 
 
232
        QWidget *topParent = topLevelWidget();
 
233
        QRect desktop = qApp->desktop()->availableGeometry( (QWidget *)topParent );
 
234
        int dh = h - height();
 
235
 
 
236
        bool showScrollBar = false;
 
237
 
 
238
        // check that our dialog's height doesn't exceed the desktop's
 
239
        if ( allowResize() && (topParent->frameGeometry().height() + dh) >= desktop.height() ) {
 
240
                // handles the case when the dialog could be resized,
 
241
                // but lineedit wants to occupy too much space, so we should limit it
 
242
                h = desktop.height() - ( topParent->frameGeometry().height() - height() );
 
243
                showScrollBar = true;
 
244
        }
 
245
        else if ( !allowResize() && (h > topParent->geometry().height()/2) ) {
 
246
                // handles the case when the dialog could not be resized(i.e. it's maximized).
 
247
                // in this case we limit maximum height of lineedit to the half of dialog's
 
248
                // full height
 
249
                h = topParent->geometry().height() / 2;
 
250
                showScrollBar = true;
 
251
        }
 
252
 
 
253
        // enable vertical scrollbar only when we're surely in need for it
 
254
        QTextEdit *textEdit = (QTextEdit *)this;
 
255
        if ( showScrollBar )
 
256
                textEdit->setVScrollBarMode( AlwaysOn );
 
257
        else
 
258
                textEdit->setVScrollBarMode( AlwaysOff );
 
259
 
 
260
        lastSize.setHeight( h );
 
261
        return lastSize;
 
262
}
 
263
 
 
264
/*!
 
265
 * Handles automatic dialog resize.
 
266
 */
 
267
void LineEdit::recalculateSize()
 
268
{
 
269
        if ( !isUpdatesEnabled() )
 
270
                return;
 
271
 
 
272
        QSize oldSize = lastSize;
 
273
        lastSize = QSize( 0, 0 ); // force sizeHint() to update
 
274
        QSize newSize = sizeHint();
 
275
 
 
276
        if ( QABS(newSize.height() - oldSize.height()) > 1 ) {
 
277
                if ( allowResize() ) {
 
278
                        parentWidget()->layout()->setEnabled( false ); // try to reduce some flicker
 
279
 
 
280
                        QWidget *topParent = topLevelWidget();
 
281
                        int dh = newSize.height() - oldSize.height();
 
282
 
 
283
                        // if we're going to shrink dialog considerably, minimum
 
284
                        // size will prevent us from doing it. Activating main
 
285
                        // layout after resize will reset minimum sizes to sensible values
 
286
                        topParent->setMinimumSize( 10, 10 );
 
287
 
 
288
                        topParent->resize( topParent->width(),
 
289
                                           topParent->height() + dh );
 
290
 
 
291
                        bool canMove = dh > 0;
 
292
                        int  newy    = topParent->y();
 
293
 
 
294
                        // try to move window to its old position
 
295
                        if ( movedWindow() && dh < 0 ) {
 
296
                                newy = initialWindowGeometry.y();
 
297
                                canMove = true;
 
298
                        }
 
299
 
 
300
                        // check, if we need to move dialog upper
 
301
                        QRect desktop = qApp->desktop()->availableGeometry( (QWidget *)topParent );
 
302
                        if ( canMove && ( newy + topParent->frameGeometry().height() >= desktop.bottom() ) ) {
 
303
                                // initialize default window position
 
304
                                if ( !movedWindow() ) {
 
305
                                        initialWindowGeometry = topParent->frameGeometry();
 
306
                                }
 
307
 
 
308
                                newy = QMAX(0, desktop.bottom() - topParent->frameGeometry().height());
 
309
                        }
 
310
 
 
311
                        if ( canMove && newy != topParent->y() ) {
 
312
                                topParent->move( topParent->x(), newy );
 
313
                                moveTo = topParent->pos();
 
314
                        }
 
315
 
 
316
                        parentWidget()->layout()->setEnabled( true );
 
317
                }
 
318
 
 
319
                // issue a layout update
 
320
                parentWidget()->layout()->activate();
 
321
        }
 
322
}
 
323
 
 
324
void LineEdit::resizeEvent( QResizeEvent *e )
 
325
{
 
326
        // issue a re-layout, just in case
 
327
        lastSize = QSize( 0, 0 ); // force sizeHint() to update
 
328
        sizeHint(); // update the size hint, and cache the value
 
329
        topLevelWidget()->layout()->activate();
 
330
 
 
331
        PsiTextView::resizeEvent( e );
 
332
}
 
333
 
 
334
void LineEdit::setUpdatesEnabled( bool enable )
 
335
{
 
336
        bool ue = isUpdatesEnabled();
 
337
        ChatEdit::setUpdatesEnabled( enable );
 
338
 
 
339
        if ( !ue && enable )
 
340
                recalculateSize();
 
341
}
 
342
 
 
343
bool LineEdit::eventFilter(QObject *watched, QEvent *e)
 
344
{
 
345
        if ( !parentWidget()->layout()->isEnabled() )
 
346
                return ChatEdit::eventFilter( watched, e );
 
347
 
 
348
        if ( e->type() == QEvent::Reparent ) {
 
349
                // In case of tabbed chats, dialog could be reparented to a higher-level dialog
 
350
                // we need to get move events from it too. And unnecessary event filters
 
351
                // are automatically cleaned up by Qt.
 
352
                topLevelWidget()->installEventFilter( this );
 
353
        }
 
354
        else if ( e->type() == QEvent::Move ) {
 
355
                QWidget *topParent = topLevelWidget();
 
356
                if ( watched == topParent ) {
 
357
                        moveTimer->start( 100, true );
 
358
                }
 
359
        }
 
360
 
 
361
        return ChatEdit::eventFilter( watched, e );
 
362
}
 
363
 
 
364
//! This function serves as a workaround for multiple move events, some of which
 
365
//! have incorrect coordinates (at least on KDE)
 
366
void LineEdit::checkMoved()
 
367
{
 
368
        QWidget *topParent = topLevelWidget();
 
369
        if ( QABS(moveTo.x() - topParent->x()) > 1 ||
 
370
             QABS(moveTo.y() - topParent->y()) > 1 ) {
 
371
                moveTo = topParent->pos();
 
372
                initialWindowGeometry = QRect( 0, 0, 0, 0 );
 
373
        }
 
374
}
 
375
 
 
376
bool LineEdit::movedWindow() const
 
377
{
 
378
        return initialWindowGeometry.left()  ||
 
379
               initialWindowGeometry.top()   ||
 
380
               initialWindowGeometry.width() ||
 
381
               initialWindowGeometry.height();
 
382
}
127
383