26 #include "folderrequester.h"
29 #include "mailcommon/kernel/mailkernel.h"
30 #include "mailcommon/search/searchpatternedit.h"
31 #include "mailcommon/widgets/regexplineedit.h"
33 #include "foldertreeview.h"
37 #include "pimcommon/folderdialog/selectmulticollectiondialog.h"
39 #include <Akonadi/CollectionModifyJob>
40 #include <Akonadi/CollectionFetchJob>
41 #include <Akonadi/EntityTreeView>
42 #include <akonadi/persistentsearchattribute.h>
43 #include <Akonadi/SearchCreateJob>
44 #include <Akonadi/ChangeRecorder>
45 #include <akonadi/standardactionmanager.h>
46 #include <Akonadi/EntityMimeTypeFilterModel>
47 #include <KActionMenu>
50 #include <KIconLoader>
51 #include <kmime/kmime_message.h>
52 #include <KStandardAction>
53 #include <KStandardGuiItem>
54 #include <KWindowSystem>
55 #include <KMessageBox>
58 #include <QCloseEvent>
60 #include <QHeaderView>
63 #include <QVBoxLayout>
66 using namespace MailCommon;
70 SearchWindow::SearchWindow(
KMMainWidget *widget,
const Akonadi::Collection &collection )
72 mCloseRequested( false ),
74 mSortOrder( Qt::AscendingOrder ),
77 mKMMainWidget( widget ),
78 mAkonadiStandardAction( 0 )
80 setCaption( i18n(
"Find Messages" ) );
82 KWindowSystem::setIcons( winId(), qApp->windowIcon().pixmap( IconSize( KIconLoader::Desktop ),
83 IconSize( KIconLoader::Desktop ) ),
84 qApp->windowIcon().pixmap( IconSize( KIconLoader::Small ),
85 IconSize( KIconLoader::Small ) ) );
90 topWidget->setLayout(lay);
93 setMainWidget( topWidget );
96 mUi.setupUi( searchWidget );
102 mStartSearchGuiItem = KGuiItem( i18nc(
"@action:button Search for messages",
"&Search" ),
QLatin1String(
"edit-find") );
103 mStopSearchGuiItem = KStandardGuiItem::stop();
104 mSearchButton = mUi.mButtonBox->addButton( mStartSearchGuiItem, QDialogButtonBox::ActionRole );
105 connect( mUi.mButtonBox, SIGNAL(rejected()), SLOT(slotClose()) );
108 mUi.mCbxFolders->setMustBeReadWrite(
false );
109 mUi.mCbxFolders->setNotAllowToCreateNewFolder(
true );
111 bool currentFolderIsSearchFolder =
false;
113 if ( !collection.hasAttribute<Akonadi::PersistentSearchAttribute>() ) {
115 mSearchPattern.append( SearchRule::createInstance(
"Subject" ) );
116 mUi.mCbxFolders->setCollection( collection );
120 currentFolderIsSearchFolder =
true;
123 mSearchPattern.deserialize( searchDescription->
description() );
127 mUi.mChkMultiFolders->setChecked(
true);
128 mCollectionId.
clear();
129 Q_FOREACH (Akonadi::Collection::Id col, lst) {
130 mCollectionId.
append(Akonadi::Collection(col));
133 const Akonadi::Collection col = searchDescription->
baseCollection();
134 if ( col.isValid() ) {
135 mUi.mChkbxSpecificFolders->setChecked(
true );
136 mUi.mCbxFolders->setCollection( col );
137 mUi.mChkSubFolders->setChecked( searchDescription->
recursive() );
139 mUi.mChkbxAllFolders->setChecked(
true );
140 mUi.mChkSubFolders->setChecked( searchDescription->
recursive() );
146 kWarning() <<
"This search was not created with KMail. It cannot be edited within it.";
147 mSearchPattern.clear();
151 mUi.mPatternEdit->setSearchPattern( &mSearchPattern );
152 connect( mUi.mPatternEdit, SIGNAL(returnPressed()),
153 this, SLOT(slotSearch()) );
156 connect( mUi.mChkbxAllFolders, SIGNAL(toggled(
bool)),
157 this, SLOT(setEnabledSearchButton(
bool)) );
159 mUi.mLbxMatches->setXmlGuiClient( mKMMainWidget->
guiClient() );
174 mUi.mLbxMatches->setSortingEnabled(
true );
176 connect( mUi.mLbxMatches, SIGNAL(customContextMenuRequested(
QPoint)),
177 this, SLOT(slotContextMenuRequested(
QPoint)) );
178 connect( mUi.mLbxMatches, SIGNAL(doubleClicked(Akonadi::Item)),
179 this, SLOT(slotViewMsg(Akonadi::Item)) );
180 connect( mUi.mLbxMatches, SIGNAL(currentChanged(Akonadi::Item)),
181 this, SLOT(slotCurrentChanged(Akonadi::Item)) );
182 connect( mUi.selectMultipleFolders, SIGNAL(clicked()),
183 this, SLOT(slotSelectMultipleFolders()));
185 connect(
KMKernel::self()->folderCollectionMonitor(), SIGNAL(collectionStatisticsChanged(Akonadi::Collection::Id,Akonadi::CollectionStatistics)),
this, SLOT(updateCollectionStatistic(Akonadi::Collection::Id,Akonadi::CollectionStatistics)) );
187 if ( currentFolderIsSearchFolder ) {
188 mFolder = collection;
189 mUi.mSearchFolderEdt->setText( collection.name() );
190 Q_ASSERT ( !mResultModel );
193 mUi.mSearchFolderEdt->setText( i18n(
"Last Search" ) );
195 mFolder = CommonKernel->collectionFromId( GlobalSettings::lastSearchCollectionId() );
197 if ( mFolder.isValid() && mFolder.name() != mUi.mSearchFolderEdt->text() ) {
198 mFolder = Akonadi::Collection();
202 connect( mUi.mSearchFolderEdt, SIGNAL(textChanged(
QString)),
203 this, SLOT(scheduleRename(
QString)) );
204 connect( &mRenameTimer, SIGNAL(timeout()),
205 this, SLOT(renameSearchFolder()) );
206 connect( mUi.mSearchFolderOpenBtn, SIGNAL(clicked()),
207 this, SLOT(openSearchFolder()) );
209 connect( mUi.mSearchResultOpenBtn, SIGNAL(clicked()),
210 this, SLOT(slotViewSelectedMsg()) );
215 if ( mainWidth || mainHeight )
216 resize( mainWidth, mainHeight );
218 connect( mSearchButton, SIGNAL(clicked()), SLOT(slotSearch()) );
219 connect(
this, SIGNAL(finished()),
this, SLOT(deleteLater()) );
220 connect(
this, SIGNAL(closeClicked()),
this,SLOT(slotClose()) );
223 RegExpLineEdit* r = mUi.mPatternEdit->findChild<RegExpLineEdit*>(
QLatin1String(
"regExpLineEdit") );
227 kDebug() <<
"SearchWindow: regExpLineEdit not found";
230 KActionCollection *ac = actionCollection();
231 mReplyAction =
new KAction( KIcon(
QLatin1String(
"mail-reply-sender") ), i18n(
"&Reply..." ),
this );
232 actionCollection()->addAction(
QLatin1String(
"search_reply"), mReplyAction );
233 connect( mReplyAction, SIGNAL(triggered(
bool)), SLOT(slotReplyToMsg()) );
235 mReplyAllAction =
new KAction( KIcon(
QLatin1String(
"mail-reply-all") ), i18n(
"Reply to &All..." ),
this );
236 actionCollection()->addAction(
QLatin1String(
"search_reply_all"), mReplyAllAction );
237 connect( mReplyAllAction, SIGNAL(triggered(
bool)), SLOT(slotReplyAllToMsg()) );
239 mReplyListAction =
new KAction( KIcon(
QLatin1String(
"mail-reply-list") ), i18n(
"Reply to Mailing-&List..." ),
this );
240 actionCollection()->addAction(
QLatin1String(
"search_reply_list"), mReplyListAction );
241 connect( mReplyListAction, SIGNAL(triggered(
bool)), SLOT(slotReplyListToMsg()) );
243 mForwardActionMenu =
new KActionMenu( KIcon(
QLatin1String(
"mail-forward") ), i18nc(
"Message->",
"&Forward" ),
this );
244 actionCollection()->addAction(
QLatin1String(
"search_message_forward"), mForwardActionMenu );
245 connect( mForwardActionMenu, SIGNAL(triggered(
bool)),
this, SLOT(slotForwardMsg()) );
247 mForwardInlineAction =
new KAction( KIcon(
QLatin1String(
"mail-forward") ),
248 i18nc(
"@action:inmenu Forward message inline.",
"&Inline..." ),
250 actionCollection()->addAction(
QLatin1String(
"search_message_forward_inline"), mForwardInlineAction );
251 connect( mForwardInlineAction, SIGNAL(triggered(
bool)), SLOT(slotForwardMsg()) );
253 mForwardAttachedAction =
new KAction( KIcon(
QLatin1String(
"mail-forward") ), i18nc(
"Message->Forward->",
"As &Attachment..." ),
this );
254 actionCollection()->addAction(
QLatin1String(
"search_message_forward_as_attachment"), mForwardAttachedAction );
255 connect( mForwardAttachedAction, SIGNAL(triggered(
bool)), SLOT(slotForwardAttachedMsg()) );
258 mForwardActionMenu->addAction( mForwardInlineAction );
259 mForwardActionMenu->addAction( mForwardAttachedAction );
261 mForwardActionMenu->addAction( mForwardAttachedAction );
262 mForwardActionMenu->addAction( mForwardInlineAction );
265 mSaveAsAction = actionCollection()->addAction( KStandardAction::SaveAs,
QLatin1String(
"search_file_save_as"),
this, SLOT(slotSaveMsg()) );
267 mSaveAtchAction =
new KAction( KIcon(
QLatin1String(
"mail-attachment") ), i18n(
"Save Attachments..." ),
this );
268 actionCollection()->addAction(
QLatin1String(
"search_save_attachments"), mSaveAtchAction );
269 connect( mSaveAtchAction, SIGNAL(triggered(
bool)), SLOT(slotSaveAttachments()) );
271 mPrintAction = actionCollection()->addAction( KStandardAction::Print,
QLatin1String(
"search_print"),
this, SLOT(slotPrintMsg()) );
273 mClearAction =
new KAction( i18n(
"Clear Selection" ),
this );
274 actionCollection()->addAction(
QLatin1String(
"search_clear_selection"), mClearAction );
275 connect( mClearAction, SIGNAL(triggered(
bool)), SLOT(slotClearSelection()) );
277 mJumpToFolderAction =
new KAction( i18n(
"Jump to original folder" ),
this );
278 actionCollection()->addAction(
QLatin1String(
"search_jump_folder"), mJumpToFolderAction );
279 connect( mJumpToFolderAction, SIGNAL(triggered(
bool)), SLOT(slotJumpToFolder()) );
282 connect( mUi.mCbxFolders, SIGNAL(folderChanged(Akonadi::Collection)),
283 this, SLOT(slotFolderActivated()) );
285 ac->addAssociatedWidget(
this );
286 foreach (
QAction* action, ac->actions() )
292 if ( mResultModel ) {
293 if ( mUi.mLbxMatches->columnWidth( 0 ) > 0 ) {
296 if ( mUi.mLbxMatches->columnWidth( 1 ) > 0 ) {
299 if ( mUi.mLbxMatches->columnWidth( 2 ) > 0 ) {
302 if ( mUi.mLbxMatches->columnWidth( 3 ) > 0 ) {
305 if ( mUi.mLbxMatches->columnWidth( 4 ) > 0 ) {
308 if ( mUi.mLbxMatches->columnWidth( 5 ) > 0 ) {
314 mResultModel->deleteLater();
320 if ( mResultModel ) {
321 mResultModel->deleteLater();
324 mResultModel->setCollection( mFolder );
327 mUi.mLbxMatches->setModel( sortproxy );
335 mUi.mLbxMatches->setColumnHidden( 6,
true );
336 mUi.mLbxMatches->setColumnHidden( 7,
true );
337 mUi.mLbxMatches->header()->setSortIndicator( 2, Qt::DescendingOrder );
338 mUi.mLbxMatches->header()->setStretchLastSection(
false );
339 mUi.mLbxMatches->header()->restoreState( mHeaderState );
341 if(!mAkonadiStandardAction)
342 mAkonadiStandardAction =
new Akonadi::StandardMailActionManager( actionCollection(),
this );
343 mAkonadiStandardAction->setItemSelectionModel( mUi.mLbxMatches->selectionModel() );
344 mAkonadiStandardAction->setCollectionSelectionModel( mKMMainWidget->
folderTreeView()->selectionModel() );
349 void SearchWindow::setEnabledSearchButton(
bool )
355 mSearchButton->setEnabled(
true );
358 void SearchWindow::updateCollectionStatistic(Akonadi::Collection::Id
id,
const Akonadi::CollectionStatistics &statistic)
361 if (
id == mFolder.id() ) {
362 genMsg = i18np(
"%1 match",
"%1 matches", statistic.count() );
364 mUi.mStatusLbl->setText( genMsg );
369 if ( event->
key() == Qt::Key_Escape && mSearchJob ) {
374 KDialog::keyPressEvent( event );
377 void SearchWindow::slotFolderActivated()
379 mUi.mChkbxSpecificFolders->setChecked(
true );
384 mUi.mChkbxSpecificFolders->setChecked(
true );
385 mUi.mCbxFolders->setCollection( collection );
388 void SearchWindow::slotSearch()
390 if (mFolder.isValid()) {
397 Akonadi::CollectionFetchJob *fetchJob =
new Akonadi::CollectionFetchJob(Akonadi::Collection(1), Akonadi::CollectionFetchJob::FirstLevel);
398 connect(fetchJob, SIGNAL(result(
KJob*)),
this, SLOT(slotSearchCollectionsFetched(
KJob*)));
401 void SearchWindow::slotSearchCollectionsFetched(
KJob *job)
404 kWarning() << job->errorString();
406 Akonadi::CollectionFetchJob *fetchJob =
static_cast<Akonadi::CollectionFetchJob*
>(job);
407 Q_FOREACH(
const Akonadi::Collection &col, fetchJob->collections()) {
408 if (col.name() == mUi.mSearchFolderEdt->text()) {
415 void SearchWindow::doSearch()
418 if ( mUi.mSearchFolderEdt->text().isEmpty() ) {
419 mUi.mSearchFolderEdt->setText( i18n(
"Last Search" ) );
423 mHeaderState = mUi.mLbxMatches->header()->saveState();
425 mUi.mLbxMatches->setModel( 0 );
427 mSortColumn = mUi.mLbxMatches->header()->sortIndicatorSection();
428 mSortOrder = mUi.mLbxMatches->header()->sortIndicatorOrder();
429 mUi.mLbxMatches->setSortingEnabled(
false );
432 mSearchJob->kill( KJob::Quietly );
433 mSearchJob->deleteLater();
437 mUi.mSearchFolderEdt->setEnabled(
false );
439 Akonadi::Collection::List searchCollections;
440 bool recursive =
false;
441 if ( mUi.mChkbxSpecificFolders->isChecked() ) {
442 const Akonadi::Collection col = mUi.mCbxFolders->collection();
443 if (!col.isValid()) {
445 mUi.mSearchFolderEdt->setEnabled(
true );
448 searchCollections << col;
449 if ( mUi.mChkSubFolders->isChecked() ) {
452 }
else if (mUi.mChkMultiFolders->isChecked()) {
453 if (!mSelectMultiCollectionDialog) {
457 mCollectionId = mSelectMultiCollectionDialog->selectedCollection();
458 Q_FOREACH(
const Akonadi::Collection &col, mCollectionId) {
459 searchCollections << col;
461 if (searchCollections.isEmpty()) {
462 mUi.mSearchFolderEdt->setEnabled(
true );
464 mQuery = Akonadi::SearchQuery();
469 mUi.mPatternEdit->updateSearchPattern();
471 SearchPattern searchPattern( mSearchPattern );
472 searchPattern.purify();
474 MailCommon::SearchPattern::SparqlQueryError queryError = MailCommon::SearchPattern::NoError;
475 queryError = searchPattern.asAkonadiQuery(mQuery);
477 case MailCommon::SearchPattern::NoError:
479 case MailCommon::SearchPattern::MissingCheck:
480 mUi.mSearchFolderEdt->setEnabled(
true );
482 mQuery = Akonadi::SearchQuery();
484 case MailCommon::SearchPattern::FolderEmptyOrNotIndexed:
485 mUi.mSearchFolderEdt->setEnabled(
true );
487 mQuery = Akonadi::SearchQuery();
489 case MailCommon::SearchPattern::EmptyResult:
490 mUi.mSearchFolderEdt->setEnabled(
true );
491 mQuery = Akonadi::SearchQuery();
494 case MailCommon::SearchPattern::NotEnoughCharacters:
495 mUi.mSearchFolderEdt->setEnabled(
true );
496 mSearchPatternWidget->
showWarningPattern(
QStringList()<<i18n(
"Contains condition cannot be used with a number of characters inferior to 4."));
497 mQuery = Akonadi::SearchQuery();
501 kDebug() << mQuery.toJSON();
502 mUi.mSearchFolderOpenBtn->setEnabled(
true );
504 if ( !mFolder.isValid() ) {
505 kDebug()<<
" create new folder " << mUi.mSearchFolderEdt->text();
506 Akonadi::SearchCreateJob *searchJob =
new Akonadi::SearchCreateJob( mUi.mSearchFolderEdt->text(), mQuery, this );
508 searchJob->setSearchCollections( searchCollections );
509 searchJob->setRecursive( recursive );
510 searchJob->setRemoteSearchEnabled(
false );
511 mSearchJob = searchJob;
513 kDebug()<<
" use existing folder " << mFolder.id();
514 Akonadi::PersistentSearchAttribute *attribute =
new Akonadi::PersistentSearchAttribute();
518 attribute->setQueryCollections( searchCollections );
519 attribute->setRecursive( recursive );
520 attribute->setRemoteSearchEnabled(
false );
521 mFolder.addAttribute(attribute);
522 mSearchJob =
new Akonadi::CollectionModifyJob( mFolder,
this );
525 connect( mSearchJob, SIGNAL(result(
KJob*)), SLOT(searchDone(
KJob*)) );
526 mUi.mProgressIndicator->start();
528 mUi.mStatusLbl->setText( i18n(
"Searching..." ) );
531 void SearchWindow::searchDone(
KJob* job )
533 Q_ASSERT( job == mSearchJob );
535 mUi.mProgressIndicator->stop();
536 if ( job->error() ) {
537 kDebug() << job->errorString();
538 KMessageBox::sorry(
this, i18n(
"Cannot get search result. %1", job->errorString() ) );
543 mUi.mSearchFolderEdt->setEnabled(
true );
544 mUi.mStatusLbl->setText( i18n(
"Search failed.") );
548 if ( Akonadi::SearchCreateJob *searchJob = qobject_cast<Akonadi::SearchCreateJob*>( mSearchJob ) ) {
549 mFolder = searchJob->createdCollection();
550 }
else if ( Akonadi::CollectionModifyJob *modifyJob = qobject_cast<Akonadi::CollectionModifyJob*>( mSearchJob ) ) {
551 mFolder = modifyJob->collection();
554 Q_ASSERT( mFolder.isValid() );
555 Q_ASSERT( mFolder.hasAttribute<Akonadi::PersistentSearchAttribute>() );
557 GlobalSettings::setLastSearchCollectionId( mFolder.id() );
563 const QByteArray search = mSearchPattern.serialize();
567 if ( mUi.mChkMultiFolders->isChecked()) {
568 searchDescription->setBaseCollection( Akonadi::Collection() );
570 Q_FOREACH (
const Akonadi::Collection &col, mCollectionId) {
573 searchDescription->setListCollection(lst);
574 }
else if (mUi.mChkbxSpecificFolders->isChecked()) {
575 const Akonadi::Collection collection = mUi.mCbxFolders->collection();
576 searchDescription->setBaseCollection( collection );
578 searchDescription->setBaseCollection( Akonadi::Collection() );
580 searchDescription->setRecursive( mUi.mChkSubFolders->isChecked() );
581 new Akonadi::CollectionModifyJob( mFolder,
this );
584 mUi.mStatusLbl->setText( i18n(
"Search complete.") );
587 if ( mCloseRequested )
590 mUi.mLbxMatches->setSortingEnabled(
true );
591 mUi.mLbxMatches->header()->setSortIndicator( mSortColumn, mSortOrder );
593 mUi.mSearchFolderEdt->setEnabled(
true );
597 void SearchWindow::slotStop()
599 mUi.mProgressIndicator->stop();
601 mSearchJob->kill( KJob::Quietly );
602 mSearchJob->deleteLater();
604 mUi.mStatusLbl->setText( i18n(
"Search stopped.") );
610 void SearchWindow::slotClose()
618 mCloseRequested =
true;
620 mSearchJob->kill( KJob::Quietly );
621 mSearchJob->deleteLater();
625 KDialog::closeEvent( event );
629 void SearchWindow::scheduleRename(
const QString &
text )
633 mRenameTimer.
start( 250 );
634 mUi.mSearchFolderOpenBtn->setEnabled(
false );
637 mUi.mSearchFolderOpenBtn->setEnabled( !text.
isEmpty() );
641 void SearchWindow::renameSearchFolder()
643 const QString name = mUi.mSearchFolderEdt->text();
644 if ( mFolder.isValid() ) {
645 const QString oldFolderName = mFolder.name();
646 if ( oldFolderName != name ) {
647 mFolder.setName( name );
648 Akonadi::CollectionModifyJob *job =
new Akonadi::CollectionModifyJob( mFolder,
this );
649 job->setProperty(
"oldfoldername", oldFolderName);
650 connect( job, SIGNAL(result(
KJob*)),
651 this, SLOT(slotSearchFolderRenameDone(
KJob*)) );
653 mUi.mSearchFolderOpenBtn->setEnabled(
true );
657 void SearchWindow::slotSearchFolderRenameDone(
KJob *job )
660 if ( job->error() ) {
661 kWarning() <<
"Job failed:" << job->errorText();
662 KMessageBox::information(
this, i18n(
"There was a problem renaming your search folder. "
663 "A common reason for this is that another search folder "
664 "with the same name already exists. Error returned \"%1\".", job->errorText() ) );
665 mUi.mSearchFolderEdt->blockSignals(
true);
666 mUi.mSearchFolderEdt->setText(job->property(
"oldfoldername").toString());
667 mUi.mSearchFolderEdt->blockSignals(
false);
671 void SearchWindow::openSearchFolder()
673 Q_ASSERT( mFolder.isValid() );
674 renameSearchFolder();
679 void SearchWindow::slotViewSelectedMsg()
684 void SearchWindow::slotViewMsg(
const Akonadi::Item &item )
686 if ( item.isValid() ) {
691 void SearchWindow::slotCurrentChanged(
const Akonadi::Item &item )
693 mUi.mSearchResultOpenBtn->setEnabled( item.isValid() );
696 void SearchWindow::enableGUI()
698 const bool searching = (mSearchJob != 0);
700 mSearchButton->setGuiItem( searching ? mStopSearchGuiItem : mStartSearchGuiItem );
702 disconnect( mSearchButton, SIGNAL(clicked()),
this, SLOT(slotSearch()) );
703 connect( mSearchButton, SIGNAL(clicked()), SLOT(slotStop()) );
705 disconnect( mSearchButton, SIGNAL(clicked()),
this, SLOT(slotStop()) );
706 connect( mSearchButton, SIGNAL(clicked()), SLOT(slotSearch()) );
712 Akonadi::Item::List messages;
714 foreach (
const QModelIndex &index, mUi.mLbxMatches->selectionModel()->selectedRows() ) {
715 const Akonadi::Item item = index.
data( Akonadi::ItemModel::ItemRole ).
value<Akonadi::Item>();
716 if ( item.isValid() )
717 messages.append( item );
725 return mUi.mLbxMatches->currentIndex().data( Akonadi::ItemModel::ItemRole ).value<Akonadi::Item>();
728 void SearchWindow::updateContextMenuActions()
731 const bool singleActions = (count == 1);
732 const bool notEmpty = (count > 0);
734 mJumpToFolderAction->
setEnabled( singleActions );
738 mReplyListAction->
setEnabled( singleActions );
745 void SearchWindow::slotContextMenuRequested(
const QPoint& )
751 updateContextMenuActions();
761 KAction *act = mAkonadiStandardAction->createAction( Akonadi::StandardActionManager::CopyItems );
762 mAkonadiStandardAction->setActionText( Akonadi::StandardActionManager::CopyItems, ki18np(
"Copy Message",
"Copy %1 Messages" ) );
764 act = mAkonadiStandardAction->createAction( Akonadi::StandardActionManager::CutItems );
765 mAkonadiStandardAction->setActionText( Akonadi::StandardActionManager::CutItems, ki18np(
"Cut Message",
"Cut %1 Messages" ) );
767 menu->
addAction( mAkonadiStandardAction->createAction( Akonadi::StandardActionManager::CopyItemToMenu ) );
768 menu->
addAction( mAkonadiStandardAction->createAction( Akonadi::StandardActionManager::MoveItemToMenu ) );
780 void SearchWindow::slotClearSelection()
782 mUi.mLbxMatches->clearSelection();
785 void SearchWindow::slotReplyToMsg()
791 void SearchWindow::slotReplyAllToMsg()
797 void SearchWindow::slotReplyListToMsg()
803 void SearchWindow::slotForwardMsg()
809 void SearchWindow::slotForwardAttachedMsg()
815 void SearchWindow::slotSaveMsg()
818 saveCommand->
start();
821 void SearchWindow::slotSaveAttachments()
824 saveCommand->
start();
827 void SearchWindow::slotPrintMsg()
835 SearchPattern p( mSearchPattern );
841 for ( it = pattern.constBegin() ; it != end ; ++it ) {
842 p.append( SearchRule::createInstance( **it ) );
846 mUi.mPatternEdit->setSearchPattern( &mSearchPattern );
849 void SearchWindow::slotSelectMultipleFolders()
851 mUi.mChkMultiFolders->setChecked(
true);
852 if (!mSelectMultiCollectionDialog) {
854 Q_FOREACH (
const Akonadi::Collection &col, mCollectionId) {
857 mSelectMultiCollectionDialog =
new PimCommon::SelectMultiCollectionDialog(KMime::Message::mimeType(), lst,
this);
859 mSelectMultiCollectionDialog->show();
862 void SearchWindow::slotJumpToFolder()
QByteArray description() const
Akonadi::Item selectedMessage() const
Provides access to the currently selected message.
void setDescription(const QByteArray &desc)
void setShortcutContext(Qt::ShortcutContext context)
virtual void setSourceModel(QAbstractItemModel *sourceModel)
virtual QByteArray text(quint32 serialNumber) const =0
void slotMessageActivated(const Akonadi::Item &)
Open a separate viewer window containing the specified message.
Akonadi::Item::List selectedMessages() const
Provides access to the list of currently selected message in the listview.
static KMKernel * self()
normal control stuff
MailCommon::FolderTreeView * folderTreeView() const
void append(const T &value)
void closeEvent(QCloseEvent *)
Reimplemented to stop searching when the window is closed.
Small helper structure which encapsulates the KMMessage created when creating a reply, and.
Akonadi::Collection baseCollection() const
void addRulesToSearchPattern(const MailCommon::SearchPattern &pattern)
Loads a search pattern into the search window, appending its rules to the current one...
void setMargin(int margin)
~SearchWindow()
Destroys the search window.
void requestSync()
Call this slot instead of directly KConfig::sync() to minimize the overall config writes...
void slotSelectCollectionFolder(const Akonadi::Collection &col)
static GlobalSettings * self()
void keyPressEvent(QKeyEvent *)
Reimplemented to react to Escape.
QVariant data(int role) const
QList< Akonadi::Collection::Id > listCollection() const
QString fromLatin1(const char *str, int size)
void showWarningPattern(const QStringList &lstError)
void hideWarningPattern()
KXMLGUIClient * guiClient() const
Returns the XML GUI client.
void activateFolder(const Akonadi::Collection &folder)
Changes the base folder for search operations to a different folder.