1 /***************************************************************************
2 * Copyright (C) 2008 by Sebastian Trueg <trueg@kde.org> *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
18 ***************************************************************************/
20 #include "commenteditwidget.h"
22 #include <QtGui/QToolButton>
23 #include <QtGui/QVBoxLayout>
24 #include <QtCore/QEventLoop>
25 #include <QtCore/QPointer>
26 #include <QtGui/QApplication>
27 #include <QtGui/QDesktopWidget>
28 #include <QtGui/QMouseEvent>
29 #include <QtGui/QFont>
38 class CommentEditWidget::Private
41 Private( CommentEditWidget
* parent
)
46 QEventLoop
* eventLoop
;
49 QToolButton
* buttonSave
;
50 QToolButton
* buttonCancel
;
54 QRect
geometryForPopupPos( const QPoint
& p
) {
55 QSize size
= q
->sizeHint();
57 // we want a little margin
58 const int margin
= KDialog::marginHint();
59 size
.setHeight( size
.height() + margin
*2 );
60 size
.setWidth( size
.width() + margin
*2 );
62 QRect screen
= QApplication::desktop()->screenGeometry( QApplication::desktop()->screenNumber( p
) );
64 // calculate popup position
65 QPoint
pos( p
.x() - size
.width()/2, p
.y() - size
.height()/2 );
67 // ensure we do not leave the desktop
68 if ( pos
.x() + size
.width() > screen
.right() ) {
69 pos
.setX( screen
.right() - size
.width() );
71 else if ( pos
.x() < screen
.left() ) {
72 pos
.setX( screen
.left() );
75 if ( pos
.y() + size
.height() > screen
.bottom() ) {
76 pos
.setY( screen
.bottom() - size
.height() );
78 else if ( pos
.y() < screen
.top() ) {
79 pos
.setY( screen
.top() );
82 return QRect( pos
, size
);
85 void _k_saveClicked();
86 void _k_cancelClicked();
93 void CommentEditWidget::Private::_k_saveClicked()
95 comment
= textEdit
->toPlainText();
101 void CommentEditWidget::Private::_k_cancelClicked()
108 CommentEditWidget::CommentEditWidget( QWidget
* parent
)
110 d( new Private( this ) )
112 setFrameStyle( QFrame::Box
|QFrame::Plain
);
113 setWindowFlags( Qt::Popup
);
115 d
->textEdit
= new KTextEdit( this );
116 d
->textEdit
->installEventFilter( this );
117 QVBoxLayout
* layout
= new QVBoxLayout( this );
118 layout
->setMargin( 0 );
119 layout
->addWidget( d
->textEdit
);
121 d
->buttonSave
= new QToolButton( d
->textEdit
);
122 d
->buttonCancel
= new QToolButton( d
->textEdit
);
123 d
->buttonSave
->setToolButtonStyle( Qt::ToolButtonTextBesideIcon
);
124 d
->buttonCancel
->setToolButtonStyle( Qt::ToolButtonTextBesideIcon
);
125 d
->buttonSave
->setAutoRaise( true );
126 d
->buttonCancel
->setAutoRaise( true );
127 d
->buttonSave
->setIcon( KIcon( "document-save" ) );
128 d
->buttonCancel
->setIcon( KIcon( "edit-delete" ) );
129 d
->buttonSave
->setText( i18nc( "@action:button", "Save" ) );
130 d
->buttonCancel
->setText( i18nc( "@action:button", "Cancel" ) );
133 fnt
.setPointSize( fnt
.pointSize()-2 );
134 d
->buttonSave
->setFont( fnt
);
135 d
->buttonCancel
->setFont( fnt
);
137 connect( d
->buttonSave
, SIGNAL(clicked()),
138 this, SLOT( _k_saveClicked() ) );
139 connect( d
->buttonCancel
, SIGNAL(clicked()),
140 this, SLOT( _k_cancelClicked() ) );
144 CommentEditWidget::~CommentEditWidget()
150 void CommentEditWidget::setComment( const QString
& s
)
156 QString
CommentEditWidget::comment()
162 bool CommentEditWidget::exec( const QPoint
& pos
)
165 d
->textEdit
->setPlainText( d
->comment
);
166 d
->textEdit
->setFocus();
167 d
->textEdit
->moveCursor( QTextCursor::End
);
168 QEventLoop eventLoop
;
169 d
->eventLoop
= &eventLoop
;
170 setGeometry( d
->geometryForPopupPos( pos
) );
173 QPointer
<QObject
> guard
= this;
174 (void) eventLoop
.exec();
175 if ( !guard
.isNull() )
181 void CommentEditWidget::mousePressEvent( QMouseEvent
* e
)
183 // clicking outside of the widget means cancel
184 if ( !rect().contains( e
->pos() ) ) {
189 QWidget::mousePressEvent( e
);
194 void CommentEditWidget::hideEvent( QHideEvent
* e
)
197 if ( d
->eventLoop
) {
198 d
->eventLoop
->exit();
203 void CommentEditWidget::updateButtons()
205 QSize sbs
= d
->buttonSave
->sizeHint();
206 QSize cbs
= d
->buttonCancel
->sizeHint();
208 // FIXME: button order
209 d
->buttonCancel
->setGeometry( QRect( QPoint( d
->textEdit
->width() - cbs
.width() - frameWidth(),
210 d
->textEdit
->height() - cbs
.height() - frameWidth() ),
212 d
->buttonSave
->setGeometry( QRect( QPoint( d
->textEdit
->width() - cbs
.width() - sbs
.width() - frameWidth(),
213 d
->textEdit
->height() - sbs
.height() - frameWidth() ),
218 void CommentEditWidget::resizeEvent( QResizeEvent
* e
)
220 QWidget::resizeEvent( e
);
225 bool CommentEditWidget::eventFilter( QObject
* watched
, QEvent
* event
)
227 if ( watched
== d
->textEdit
&& event
->type() == QEvent::KeyPress
) {
228 QKeyEvent
* ke
= static_cast<QKeyEvent
*>( event
);
229 kDebug() << "keypress:" << ke
->key() << ke
->modifiers();
230 if ( ( ke
->key() == Qt::Key_Enter
||
231 ke
->key() == Qt::Key_Return
) &&
232 ke
->modifiers() & Qt::ControlModifier
) {
238 return QFrame::eventFilter( watched
, event
);
241 #include "commenteditwidget.moc"