SVN_SILENT made messages (.desktop file)
[kdepim.git] / knode / kncomposerview.cpp
blob5cb2939e27df4b29fd4024b0b8c58e613c4a2f86
1 /*
2 KNode, the KDE newsreader
3 Copyright (c) 1999-2007 the KNode authors.
4 See file AUTHORS for details
5 Copyright (c) 2010 Olivier Trichet <nive@nivalis.org>
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11 You should have received a copy of the GNU General Public License
12 along with this program; if not, write to the Free Software Foundation,
13 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, US
16 #include "kncomposerview.h"
18 #include "kncomposereditor.h"
19 #include "knglobals.h"
20 #include "settings.h"
22 #include <KLocale>
23 #include <KPIMIdentities/IdentityCombo>
24 #include <KPIMIdentities/Identity>
25 #include <KPIMIdentities/IdentityManager>
26 #include <KPIMUtils/Email>
29 namespace KNode {
30 namespace Composer {
33 View::View( KNComposer *composer )
34 : QSplitter( Qt::Vertical, composer ),
35 mAttachmentSetup( false )
37 setupUi( this );
39 setChildrenCollapsible( false );
40 mAttachmentWidget->hide();
42 //From
43 mFromEdit->setView( this );
44 mFromEdit->enableCompletion( false );
45 mEdtList.append( mFromEdit );
46 showFrom( false );
48 //To
49 mToEdit->setView( this );
50 mToEdit->enableCompletion( true );
51 mEdtList.append( mToEdit );
52 connect( mToButton, SIGNAL(clicked(bool)),
53 parent(), SLOT(slotToBtnClicked()) );
55 //Newsgroups
56 mGroupsEdit->setView( this );
57 mGroupsEdit->enableCompletion( false );
58 mEdtList.append( mGroupsEdit );
59 connect( mGroupsEdit, SIGNAL(editingFinished()),
60 this, SLOT(slotGroupsChanged()) );
61 connect( mGroupsButton, SIGNAL(clicked()),
62 parent(), SLOT(slotGroupsBtnClicked()) );
64 //Followup-to
65 connect( mFollowuptoEdit, SIGNAL(focused()),
66 this, SLOT(hideFollowuptoHint()) );
68 //subject
69 mSubjectEdit->setView( this );
70 mSubjectEdit->enableCompletion( false );
71 mEdtList.append( mSubjectEdit );
72 connect( mSubjectEdit, SIGNAL(textChanged(QString)),
73 parent(), SLOT(slotSubjectChanged(QString)) );
75 //Editors
76 mEditor->switchToPlainText();
77 mEditor->setMinimumHeight(50);
79 connect( mExternalKillSwitch, SIGNAL(clicked(bool)),
80 this, SIGNAL(closeExternalEditor()) );
81 hideExternalNotification();
82 mExternalKillSwitch->setIcon( KIcon( "application-exit" ) );
84 // Identities
85 connect( mIdentitySelector, SIGNAL(identityChanged(uint)),
86 this, SLOT(slotIdentityChanged(uint)) );
87 setIdentity( KNGlobals::self()->identityManager()->defaultIdentity().uoid() );
91 View::~View()
93 if ( mAttachmentsList->topLevelItemCount() > 0 ) { // The attachment view was visible
94 KConfigGroup conf( knGlobals.config(), "POSTNEWS");
96 conf.writeEntry("Att_Splitter",sizes()); // save splitter pos
98 QList<int> lst; // save header sizes
99 QHeaderView *h = mAttachmentsList->header();
100 for ( int i = 0 ; i < h->count() ; ++i ) {
101 lst << h->sectionSize(i);
103 conf.writeEntry("Att_Headers",lst);
108 void View::completeSetup( bool firstEdit, KNComposer::MessageMode mode )
110 if ( firstEdit ) {
111 // now we place the cursor at the end of the quoted text / below the attribution line
112 if ( KNGlobals::self()->settings()->cursorOnTop() ) {
113 // FIXME: hack: counting the number of \n\n to catch end of introduction (see KNArticleFactory::createReply())
114 int dbleLfCount = KNGlobals::self()->settings()->intro().count( "%L%L" );
115 const QString text = mEditor->textOrHtml();
116 int pos = 0;
117 while ( dbleLfCount >= 0 ) {
118 pos = text.indexOf( QLatin1String( "\n\n" ), pos );
119 pos += 2;
120 --dbleLfCount;
122 mEditor->setCursorPositionFromStart( pos - 1 );
123 } else {
124 mEditor->setCursorPositionFromStart( mEditor->document()->characterCount() - 1 );
127 if ( knGlobals.settings()->appendOwnSignature() ) {
128 appendSignature();
130 } else {
131 mEditor->setCursorPositionFromStart( 0 );
133 mEditor->document()->setModified( false );
135 setMessageMode( mode );
137 // Focus
138 mEditor->setFocus();
139 if ( mSubjectEdit->text().length() == 0 ) {
140 mSubjectEdit->setFocus();
142 if ( mGroupsEdit->text().length() == 0 && mode == KNComposer::news ) {
143 mGroupsEdit->setFocus();
145 if ( mToEdit->text().length() == 0 && mode == KNComposer::mail ) {
146 mToEdit->setFocus();
151 void View::focusNextPrevEdit( const QWidget *aCur, bool aNext )
153 QList<QWidget*>::Iterator it;
155 if ( !aCur ) {
156 it = --( mEdtList.end() );
157 } else {
158 for ( QList<QWidget*>::Iterator it2 = mEdtList.begin(); it2 != mEdtList.end(); ++it2 ) {
159 if ( (*it2) == aCur ) {
160 it = it2;
161 break;
164 if ( it == mEdtList.end() )
165 return;
166 if ( aNext )
167 ++it;
168 else {
169 if ( it != mEdtList.begin() )
170 --it;
171 else
172 return;
175 if ( it != mEdtList.end() ) {
176 if ( (*it)->isVisible() )
177 (*it)->setFocus();
178 } else if ( aNext )
179 mEditor->setFocus();
182 void View::setComposingFont( const QFont &font )
184 mSubjectEdit->setFont( font );
185 mToEdit->setFont( font );
186 mGroupsEdit->setFont( font );
187 mFollowuptoEdit->setFont( font );
188 mEditor->setFontForWholeText( font );
192 void View::setMessageMode( KNComposer::MessageMode mode )
194 showTo( mode != KNComposer::news );
196 showGroups( mode != KNComposer::mail );
197 showFollowupto( mode != KNComposer::mail );
201 uint View::selectedIdentity() const
203 return mIdentitySelector->currentIdentity();
206 void View::setIdentity( uint uoid )
208 mIdentitySelector->setCurrentIdentity( uoid );
209 // mIdentitySelector will emit its identityChanged(uint) signal
210 // that is connected to slotIdentityChanged(uint)
213 void View::slotIdentityChanged( uint uoid )
215 KPIMIdentities::IdentityManager *im = KNGlobals::self()->identityManager();
216 KPIMIdentities::Identity identity = im->identityForUoid( uoid );
217 setFrom( identity.fullEmailAddr() );
218 if ( KPIMUtils::isValidAddress( from() ) != KPIMUtils::AddressOk ) {
219 showFrom( true );
224 const QString View::from()
226 return mFromEdit->text();
229 void View::setFrom( const QString& from )
231 mFromEdit->setText( from );
235 const QStringList View::groups() const
237 const QRegExp r = QRegExp( "\\s*,\\s*", Qt::CaseInsensitive, QRegExp::RegExp2 );
238 return mGroupsEdit->text().split( r, QString::SkipEmptyParts );
241 void View::setGroups( const QString &groups )
243 mGroupsEdit->setText( groups );
244 slotGroupsChanged(); // update the followup-to
247 void View::slotGroupsChanged()
249 QStringList groupsList = groups();
250 int groupsCount = groupsList.size();
251 groupsList.append( QString() );
253 const QString currFup2 = mFollowuptoEdit->currentText();
254 int i = groupsList.indexOf( currFup2 );
255 if ( i == -1 ) {
256 groupsList.prepend( currFup2 );
257 } else {
258 groupsList.move( i, 0 );
261 mFollowuptoEdit->clear();
262 mFollowuptoEdit->addItems( groupsList );
264 // Display an hint about fu2
265 if ( groupsCount > 1 ) {
266 displayFollowuptoHint();
267 } else {
268 hideFollowuptoHint();
273 const QString View::emailRecipient() const
275 return mToEdit->text();
278 void View::setEmailRecipient( const QString& to )
280 mToEdit->setText( to );
284 const QStringList View::followupTo() const
286 const QRegExp r = QRegExp( "\\s*,\\s*", Qt::CaseInsensitive, QRegExp::RegExp2 );
287 return mFollowuptoEdit->currentText().split( r, QString::SkipEmptyParts );
290 void View::setFollowupTo( const QString &followupTo )
292 hideFollowuptoHint();
293 mFollowuptoEdit->setEditText( followupTo );
296 void View::displayFollowuptoHint()
298 const QString hint = i18nc( "@info/plain This message is place, as an inactive text, in the Followup-To "
299 "line edit of the message composer when the user select more than one "
300 "group to post his/her message.",
301 "Choose an appropriate group to redirect replies..." );
302 if ( mFollowuptoEdit->currentText().isEmpty() ) {
303 QLineEdit *l = mFollowuptoEdit->lineEdit();
304 QPalette palette = l->palette();
305 KColorScheme::adjustForeground( palette, KColorScheme::InactiveText );
306 l->setPalette( palette );
307 l->setText( hint );
311 void View::hideFollowuptoHint()
313 const QString hint = i18nc( "@info/plain This message is place, as an inactive text, in the Followup-To "
314 "line edit of the message composer when the user select more than one "
315 "group to post his/her message.",
316 "Choose an appropriate group to redirect replies..." );
317 if ( mFollowuptoEdit->currentText() == hint ) {
318 QLineEdit *l = mFollowuptoEdit->lineEdit();
319 QPalette palette = l->palette();
320 KColorScheme::adjustForeground( palette, KColorScheme::NormalText );
321 l->setPalette( palette );
322 l->setText( QString() );
327 const QString View::subject() const
329 return mSubjectEdit->text();
332 void View::setSubject( const QString &subject )
334 mSubjectEdit->setText( subject );
338 KNComposerEditor * View::editor() const
340 return mEditor;
345 void View::appendSignature()
347 KPIMIdentities::IdentityManager *im = KNGlobals::self()->identityManager();
348 KPIMIdentities::Identity identity = im->identityForUoid( selectedIdentity() );
349 identity.signature().insertIntoTextEdit( KPIMIdentities::Signature::End,
350 KPIMIdentities::Signature::AddSeparator,
351 mEditor );
356 void View::showIdentity( bool show )
358 mIdentitySelectorLabel->setVisible( show );
359 mIdentitySelector->setVisible( show );
362 void View::showFrom( bool show )
364 mFromLabel->setVisible( show );
365 mFromEdit->setVisible( show );
368 void View::showTo( bool show )
370 mToLabel->setVisible( show );
371 mToEdit->setVisible( show );
372 mToButton->setVisible( show );
375 void View::showGroups( bool show )
377 mGroupsLabel->setVisible( show );
378 mGroupsEdit->setVisible( show );
379 mGroupsButton->setVisible( show );
382 void View::showFollowupto( bool show )
384 mFollowuptoLabel->setVisible( show );
385 mFollowuptoEdit->setVisible( show );
388 void View::showSubject( bool show )
390 mSubjetLabel->setVisible( show );
391 mSubjectEdit->setVisible( show );
396 void View::showAttachmentView()
398 if ( !mAttachmentSetup ) {
399 mAttachmentSetup = true;
401 //connections
402 connect( mAttachmentsList, SIGNAL(itemSelectionChanged()),
403 this, SLOT(slotAttachmentSelectionChanged()) );
405 connect( mAttachmentsList, SIGNAL(contextMenuRequested(QPoint)),
406 parent(), SLOT(slotAttachmentPopup(QPoint)) );
408 connect( mAttachmentsList, SIGNAL(deletePressed()),
409 this, SLOT(removeCurrentAttachment()) );
410 connect( mAttachmentsList, SIGNAL(attachmentRemoved(KNAttachment::Ptr,bool)),
411 parent(), SLOT(slotAttachmentRemoved(KNAttachment::Ptr,bool)) );
413 connect( mAttachmentsList, SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)),
414 mAttachmentsList, SLOT(editCurrentAttachment()) );
415 connect( mAttachmentsList, SIGNAL(returnPressed()),
416 mAttachmentsList, SLOT(editCurrentAttachment()) );
417 connect( mAttachmentsList, SIGNAL(itemChanged(QTreeWidgetItem*,int)),
418 parent(), SLOT(slotAttachmentChanged()) );
420 //buttons
421 connect( mAttachmentAddButton, SIGNAL(clicked()),
422 parent(), SLOT(slotAttachFile()) );
424 mAttachmentRemoveButton->setEnabled( false );
425 connect( mAttachmentRemoveButton, SIGNAL(clicked()),
426 this, SLOT(removeCurrentAttachment()) );
428 mAttachmentPropertiesButton->setEnabled( false );
429 connect( mAttachmentPropertiesButton, SIGNAL(clicked()),
430 mAttachmentsList, SLOT(editCurrentAttachment()) );
433 if ( !mAttachmentWidget->isVisible() ) {
434 mAttachmentWidget->show();
436 KConfigGroup conf(knGlobals.config(), "POSTNEWS");
438 QList<int> lst = conf.readEntry("Att_Splitter",QList<int>());
439 if(lst.count()!=2)
440 lst << 267 << 112;
441 setSizes(lst);
443 lst=conf.readEntry("Att_Headers",QList<int>());
444 QHeaderView *h = mAttachmentsList->header();
445 if ( lst.count() == h->count() ) {
446 for( int i = 0 ; i < h->count() ; ++i) {
447 h->resizeSection( i, lst[ i ] );
453 void View::hideAttachmentView()
455 mAttachmentWidget->hide();
458 void View::addAttachment( KNAttachment::Ptr attachment )
460 AttachmentViewItem *item = new AttachmentViewItem( mAttachmentsList, attachment );
461 mAttachmentsList->addTopLevelItem( item );
464 const QList<KNAttachment::Ptr> View::attachments() const
466 return mAttachmentsList->attachments();
469 void View::removeCurrentAttachment()
471 mAttachmentsList->removeCurrentAttachment();
474 void View::editCurrentAttachment()
476 mAttachmentsList->editCurrentAttachment();
479 void View::slotAttachmentSelectionChanged()
481 bool e = !mAttachmentsList->selectedItems().isEmpty();
482 mAttachmentRemoveButton->setEnabled( e );
483 mAttachmentPropertiesButton->setEnabled( e );
488 void View::showExternalNotification()
490 mEditorsStack->setCurrentWidget( mExternalEditorNotification );
494 void View::hideExternalNotification()
496 mEditorsStack->setCurrentWidget( mEditor );
500 } // namespace Composer
501 } // namespace KNode