26 #include "folderrequester.h"
32 #include "mailcommon/kernel/mailkernel.h"
33 #include "mailcommon/search/searchpatternedit.h"
34 #include "mailcommon/widgets/regexplineedit.h"
36 #include "foldertreeview.h"
40 #include "mailcommon/folderdialog/selectmulticollectiondialog.h"
42 #include <Akonadi/CollectionModifyJob>
43 #include <Akonadi/EntityTreeView>
44 #include <akonadi/persistentsearchattribute.h>
45 #include <Akonadi/SearchCreateJob>
46 #include <Akonadi/ChangeRecorder>
47 #include <akonadi/standardactionmanager.h>
48 #include <Akonadi/EntityMimeTypeFilterModel>
49 #include <KActionMenu>
51 #include <KDialogButtonBox>
53 #include <KIconLoader>
55 #include <kmime/kmime_message.h>
56 #include <KStandardAction>
57 #include <KStandardGuiItem>
58 #include <KWindowSystem>
59 #include <KMessageBox>
62 #include <QCloseEvent>
64 #include <QHeaderView>
67 #include <QRadioButton>
68 #include <QVBoxLayout>
71 using namespace MailCommon;
75 SearchWindow::SearchWindow(
KMMainWidget *widget,
const Akonadi::Collection &collection )
77 mCloseRequested( false ),
79 mSortOrder( Qt::AscendingOrder ),
82 mKMMainWidget( widget ),
83 mAkonadiStandardAction( 0 )
85 setCaption( i18n(
"Find Messages" ) );
87 KWindowSystem::setIcons( winId(), qApp->windowIcon().pixmap( IconSize( KIconLoader::Desktop ),
88 IconSize( KIconLoader::Desktop ) ),
89 qApp->windowIcon().pixmap( IconSize( KIconLoader::Small ),
90 IconSize( KIconLoader::Small ) ) );
93 QVBoxLayout *lay =
new QVBoxLayout;
95 topWidget->setLayout(lay);
97 lay->addWidget(mSearchPatternWidget);
98 setMainWidget( topWidget );
101 mUi.setupUi( searchWidget );
103 lay->addWidget(searchWidget);
107 mStartSearchGuiItem = KGuiItem( i18nc(
"@action:button Search for messages",
"&Search" ), QLatin1String(
"edit-find") );
108 mStopSearchGuiItem = KStandardGuiItem::stop();
109 mSearchButton = mUi.mButtonBox->addButton( mStartSearchGuiItem, QDialogButtonBox::ActionRole );
110 connect( mUi.mButtonBox, SIGNAL(rejected()), SLOT(slotClose()) );
112 QPushButton *debugButton = mUi.mButtonBox->addButton( i18n(
"Debug query"), QDialogButtonBox::ActionRole );
113 connect(debugButton, SIGNAL(clicked(
bool)), SLOT(slotDebugQuery()));
115 searchWidget->layout()->setMargin( 0 );
117 mUi.mCbxFolders->setMustBeReadWrite(
false );
118 mUi.mCbxFolders->setNotAllowToCreateNewFolder(
true );
120 bool currentFolderIsSearchFolder =
false;
122 if ( !collection.hasAttribute<Akonadi::PersistentSearchAttribute>() ) {
124 mSearchPattern.append( SearchRule::createInstance(
"Subject" ) );
125 mUi.mCbxFolders->setCollection( collection );
129 currentFolderIsSearchFolder =
true;
132 mSearchPattern.deserialize( searchDescription->
description() );
135 if (!lst.isEmpty()) {
136 mUi.mChkMultiFolders->setChecked(
true);
137 mCollectionId.clear();
138 Q_FOREACH (Akonadi::Collection::Id col, lst) {
139 mCollectionId.append(Akonadi::Collection(col));
142 const Akonadi::Collection col = searchDescription->
baseCollection();
143 if ( col.isValid() ) {
144 mUi.mChkbxSpecificFolders->setChecked(
true );
145 mUi.mCbxFolders->setCollection( col );
146 mUi.mChkSubFolders->setChecked( searchDescription->
recursive() );
148 mUi.mChkbxAllFolders->setChecked(
true );
149 mUi.mChkSubFolders->setChecked( searchDescription->
recursive() );
155 kWarning() <<
"This search was not created with KMail. It cannot be edited within it.";
156 mSearchPattern.clear();
160 mUi.mPatternEdit->setSearchPattern( &mSearchPattern );
161 connect( mUi.mPatternEdit, SIGNAL(returnPressed()),
162 this, SLOT(slotSearch()) );
165 connect( mUi.mChkbxAllFolders, SIGNAL(toggled(
bool)),
166 this, SLOT(setEnabledSearchButton(
bool)) );
168 mUi.mLbxMatches->setXmlGuiClient( mKMMainWidget->
guiClient() );
183 mUi.mLbxMatches->setSortingEnabled(
true );
185 connect( mUi.mLbxMatches, SIGNAL(customContextMenuRequested(QPoint)),
186 this, SLOT(slotContextMenuRequested(QPoint)) );
187 connect( mUi.mLbxMatches, SIGNAL(clicked(Akonadi::Item)),
188 this, SLOT(slotShowMsg(Akonadi::Item)) );
189 connect( mUi.mLbxMatches, SIGNAL(doubleClicked(Akonadi::Item)),
190 this, SLOT(slotViewMsg(Akonadi::Item)) );
191 connect( mUi.mLbxMatches, SIGNAL(currentChanged(Akonadi::Item)),
192 this, SLOT(slotCurrentChanged(Akonadi::Item)) );
193 connect( mUi.selectMultipleFolders, SIGNAL(clicked()),
194 this, SLOT(slotSelectMultipleFolders()));
196 connect(
KMKernel::self()->folderCollectionMonitor(), SIGNAL(collectionStatisticsChanged(Akonadi::Collection::Id,Akonadi::CollectionStatistics)),
this, SLOT(updateCollectionStatistic(Akonadi::Collection::Id,Akonadi::CollectionStatistics)) );
198 if ( currentFolderIsSearchFolder ) {
199 mFolder = collection;
200 mUi.mSearchFolderEdt->setText( collection.name() );
201 Q_ASSERT ( !mResultModel );
204 mUi.mSearchFolderEdt->setText( i18n(
"Last Search" ) );
206 mFolder = CommonKernel->collectionFromId( GlobalSettings::lastSearchCollectionId() );
208 if ( mFolder.isValid() && mFolder.name() != mUi.mSearchFolderEdt->text() ) {
209 mFolder = Akonadi::Collection();
213 connect( mUi.mSearchFolderEdt, SIGNAL(textChanged(QString)),
214 this, SLOT(scheduleRename(QString)) );
215 connect( &mRenameTimer, SIGNAL(timeout()),
216 this, SLOT(renameSearchFolder()) );
217 connect( mUi.mSearchFolderOpenBtn, SIGNAL(clicked()),
218 this, SLOT(openSearchFolder()) );
220 connect( mUi.mSearchResultOpenBtn, SIGNAL(clicked()),
221 this, SLOT(slotViewSelectedMsg()) );
226 if ( mainWidth || mainHeight )
227 resize( mainWidth, mainHeight );
229 connect( mSearchButton, SIGNAL(clicked()), SLOT(slotSearch()) );
230 connect(
this, SIGNAL(finished()),
this, SLOT(deleteLater()) );
231 connect(
this, SIGNAL(closeClicked()),
this,SLOT(slotClose()) );
234 RegExpLineEdit* r = mUi.mPatternEdit->findChild<RegExpLineEdit*>( QLatin1String(
"regExpLineEdit") );
238 kDebug() <<
"SearchWindow: regExpLineEdit not found";
241 KActionCollection *ac = actionCollection();
242 mReplyAction =
new KAction( KIcon( QLatin1String(
"mail-reply-sender") ), i18n(
"&Reply..." ),
this );
243 actionCollection()->addAction( QLatin1String(
"search_reply"), mReplyAction );
244 connect( mReplyAction, SIGNAL(triggered(
bool)), SLOT(slotReplyToMsg()) );
246 mReplyAllAction =
new KAction( KIcon( QLatin1String(
"mail-reply-all") ), i18n(
"Reply to &All..." ),
this );
247 actionCollection()->addAction( QLatin1String(
"search_reply_all"), mReplyAllAction );
248 connect( mReplyAllAction, SIGNAL(triggered(
bool)), SLOT(slotReplyAllToMsg()) );
250 mReplyListAction =
new KAction( KIcon( QLatin1String(
"mail-reply-list") ), i18n(
"Reply to Mailing-&List..." ),
this );
251 actionCollection()->addAction(QLatin1String(
"search_reply_list"), mReplyListAction );
252 connect( mReplyListAction, SIGNAL(triggered(
bool)), SLOT(slotReplyListToMsg()) );
254 mForwardActionMenu =
new KActionMenu( KIcon( QLatin1String(
"mail-forward") ), i18nc(
"Message->",
"&Forward" ),
this );
255 actionCollection()->addAction( QLatin1String(
"search_message_forward"), mForwardActionMenu );
256 connect( mForwardActionMenu, SIGNAL(triggered(
bool)),
this, SLOT(slotForwardMsg()) );
258 mForwardInlineAction =
new KAction( KIcon( QLatin1String(
"mail-forward") ),
259 i18nc(
"@action:inmenu Forward message inline.",
"&Inline..." ),
261 actionCollection()->addAction( QLatin1String(
"search_message_forward_inline"), mForwardInlineAction );
262 connect( mForwardInlineAction, SIGNAL(triggered(
bool)), SLOT(slotForwardMsg()) );
264 mForwardAttachedAction =
new KAction( KIcon( QLatin1String(
"mail-forward") ), i18nc(
"Message->Forward->",
"As &Attachment..." ),
this );
265 actionCollection()->addAction( QLatin1String(
"search_message_forward_as_attachment"), mForwardAttachedAction );
266 connect( mForwardAttachedAction, SIGNAL(triggered(
bool)), SLOT(slotForwardAttachedMsg()) );
269 mForwardActionMenu->addAction( mForwardInlineAction );
270 mForwardActionMenu->addAction( mForwardAttachedAction );
272 mForwardActionMenu->addAction( mForwardAttachedAction );
273 mForwardActionMenu->addAction( mForwardInlineAction );
276 mSaveAsAction = actionCollection()->addAction( KStandardAction::SaveAs, QLatin1String(
"search_file_save_as"),
this, SLOT(slotSaveMsg()) );
278 mSaveAtchAction =
new KAction( KIcon( QLatin1String(
"mail-attachment") ), i18n(
"Save Attachments..." ),
this );
279 actionCollection()->addAction( QLatin1String(
"search_save_attachments"), mSaveAtchAction );
280 connect( mSaveAtchAction, SIGNAL(triggered(
bool)), SLOT(slotSaveAttachments()) );
282 mPrintAction = actionCollection()->addAction( KStandardAction::Print, QLatin1String(
"search_print"),
this, SLOT(slotPrintMsg()) );
284 mClearAction =
new KAction( i18n(
"Clear Selection" ),
this );
285 actionCollection()->addAction( QLatin1String(
"search_clear_selection"), mClearAction );
286 connect( mClearAction, SIGNAL(triggered(
bool)), SLOT(slotClearSelection()) );
288 connect( mUi.mCbxFolders, SIGNAL(folderChanged(Akonadi::Collection)),
289 this, SLOT(slotFolderActivated()) );
291 ac->addAssociatedWidget(
this );
292 foreach ( QAction* action, ac->actions() )
293 action->setShortcutContext( Qt::WidgetWithChildrenShortcut );
298 if ( mResultModel ) {
299 if ( mUi.mLbxMatches->columnWidth( 0 ) > 0 ) {
302 if ( mUi.mLbxMatches->columnWidth( 1 ) > 0 ) {
305 if ( mUi.mLbxMatches->columnWidth( 2 ) > 0 ) {
308 if ( mUi.mLbxMatches->columnWidth( 3 ) > 0 ) {
311 if ( mUi.mLbxMatches->columnWidth( 4 ) > 0 ) {
314 if ( mUi.mLbxMatches->columnWidth( 5 ) > 0 ) {
320 mResultModel->deleteLater();
326 if ( mResultModel ) {
327 mResultModel->deleteLater();
330 mResultModel->setCollection( mFolder );
332 sortproxy->setSourceModel( mResultModel );
333 mUi.mLbxMatches->setModel( sortproxy );
341 mUi.mLbxMatches->setColumnHidden( 6,
true );
342 mUi.mLbxMatches->setColumnHidden( 7,
true );
343 mUi.mLbxMatches->header()->setSortIndicator( 2, Qt::DescendingOrder );
344 mUi.mLbxMatches->header()->setStretchLastSection(
false );
345 mUi.mLbxMatches->header()->restoreState( mHeaderState );
347 if(!mAkonadiStandardAction)
348 mAkonadiStandardAction =
new Akonadi::StandardMailActionManager( actionCollection(),
this );
349 mAkonadiStandardAction->setItemSelectionModel( mUi.mLbxMatches->selectionModel() );
350 mAkonadiStandardAction->setCollectionSelectionModel( mKMMainWidget->
folderTreeView()->selectionModel() );
355 void SearchWindow::setEnabledSearchButton(
bool )
361 mSearchButton->setEnabled(
true );
364 void SearchWindow::updateCollectionStatistic(Akonadi::Collection::Id
id,Akonadi::CollectionStatistics statistic)
367 if (
id == mFolder.id() ) {
368 genMsg = i18np(
"%1 match",
"%1 matches", statistic.count() );
370 mUi.mStatusLbl->setText( genMsg );
375 if ( event->key() == Qt::Key_Escape && mSearchJob ) {
380 KDialog::keyPressEvent( event );
383 void SearchWindow::slotFolderActivated()
385 mUi.mChkbxSpecificFolders->setChecked(
true );
390 mUi.mChkbxSpecificFolders->setChecked(
true );
391 mUi.mCbxFolders->setCollection( collection );
394 void SearchWindow::slotSearch()
397 if ( mUi.mSearchFolderEdt->text().isEmpty() ) {
398 mUi.mSearchFolderEdt->setText( i18n(
"Last Search" ) );
402 mHeaderState = mUi.mLbxMatches->header()->saveState();
404 mUi.mLbxMatches->setModel( 0 );
406 mSortColumn = mUi.mLbxMatches->header()->sortIndicatorSection();
407 mSortOrder = mUi.mLbxMatches->header()->sortIndicatorOrder();
408 mUi.mLbxMatches->setSortingEnabled(
false );
411 mSearchJob->kill( KJob::Quietly );
412 mSearchJob->deleteLater();
416 mUi.mSearchFolderEdt->setEnabled(
false );
419 if ( mUi.mChkbxSpecificFolders->isChecked() ) {
420 const Akonadi::Collection col = mUi.mCbxFolders->collection();
421 if (!col.isValid()) {
422 mSearchPatternWidget->
showWarningPattern(QStringList()<<i18n(
"You did not selected a valid folder."));
423 mUi.mSearchFolderEdt->setEnabled(
true );
426 urls << col.url( Akonadi::Collection::UrlShort );
427 if ( mUi.mChkSubFolders->isChecked() ) {
430 }
else if (mUi.mChkMultiFolders->isChecked()) {
431 if (!mSelectMultiCollectionDialog) {
434 mCollectionId = mSelectMultiCollectionDialog->selectedCollection();
435 Q_FOREACH(
const Akonadi::Collection &col, mCollectionId) {
436 urls << col.url( Akonadi::Collection::UrlShort );
438 if (urls.isEmpty()) {
439 mUi.mSearchFolderEdt->setEnabled(
true );
440 mSearchPatternWidget->
showWarningPattern(QStringList()<<i18n(
"You forgot to select collections."));
446 mUi.mPatternEdit->updateSearchPattern();
448 SearchPattern searchPattern( mSearchPattern );
449 searchPattern.purify();
451 MailCommon::SearchPattern::SparqlQueryError queryError = MailCommon::SearchPattern::NoError;
452 queryError = searchPattern.asSparqlQuery(mQuery, urls);
453 const QString queryLanguage = QLatin1String(
"SPARQL");
456 case MailCommon::SearchPattern::NoError:
458 case MailCommon::SearchPattern::MissingCheck:
459 mUi.mSearchFolderEdt->setEnabled(
true );
460 mSearchPatternWidget->
showWarningPattern(QStringList()<<i18n(
"You forgot to define condition."));
463 case MailCommon::SearchPattern::FolderEmptyOrNotIndexed:
464 mUi.mSearchFolderEdt->setEnabled(
true );
465 mSearchPatternWidget->
showWarningPattern(QStringList()<<i18n(
"All folders selected are empty or were not indexed."));
468 case MailCommon::SearchPattern::EmptyResult:
469 mUi.mSearchFolderEdt->setEnabled(
true );
471 mUi.mStatusLbl->setText( i18n(
"No message found.") );
474 case MailCommon::SearchPattern::NotEnoughCharacters:
475 mUi.mSearchFolderEdt->setEnabled(
true );
476 mSearchPatternWidget->
showWarningPattern(QStringList()<<i18n(
"Contains condition cannot be used with a number of characters inferior to 4."));
481 qDebug() << queryLanguage;
483 mUi.mSearchFolderOpenBtn->setEnabled(
true );
485 if ( !mFolder.isValid() ) {
486 qDebug()<<
" create new folder";
489 mSearchJob =
new Akonadi::SearchCreateJob( mUi.mSearchFolderEdt->text(), mQuery, this );
491 qDebug()<<
" use existing folder";
492 Akonadi::PersistentSearchAttribute *attribute = mFolder.attribute<Akonadi::PersistentSearchAttribute>();
493 attribute->setQueryLanguage( queryLanguage );
494 attribute->setQueryString( mQuery );
495 mSearchJob =
new Akonadi::CollectionModifyJob( mFolder,
this );
498 connect( mSearchJob, SIGNAL(result(
KJob*)), SLOT(searchDone(
KJob*)) );
500 mUi.mStatusLbl->setText( i18n(
"Searching..." ) );
503 void SearchWindow::searchDone(
KJob* job )
505 Q_ASSERT( job == mSearchJob );
506 QMetaObject::invokeMethod(
this,
"enableGUI", Qt::QueuedConnection );
507 if ( job->error() ) {
508 KMessageBox::sorry(
this, i18n(
"Cannot get search result. %1", job->errorString() ) );
513 mUi.mSearchFolderEdt->setEnabled(
true );
517 if ( Akonadi::SearchCreateJob *searchJob = qobject_cast<Akonadi::SearchCreateJob*>( mSearchJob ) ) {
518 mFolder = searchJob->createdCollection();
519 }
else if ( Akonadi::CollectionModifyJob *modifyJob = qobject_cast<Akonadi::CollectionModifyJob*>( mSearchJob ) ) {
520 mFolder = modifyJob->collection();
523 Q_ASSERT( mFolder.isValid() );
524 Q_ASSERT( mFolder.hasAttribute<Akonadi::PersistentSearchAttribute>() );
526 GlobalSettings::setLastSearchCollectionId( mFolder.id() );
532 const QByteArray search = mSearchPattern.serialize();
533 Q_ASSERT( !search.isEmpty() );
536 if ( mUi.mChkMultiFolders->isChecked()) {
537 searchDescription->setBaseCollection( Akonadi::Collection() );
539 Q_FOREACH (
const Akonadi::Collection &col, mCollectionId) {
542 searchDescription->setListCollection(lst);
543 }
else if (mUi.mChkbxSpecificFolders->isChecked()) {
544 const Akonadi::Collection collection = mUi.mCbxFolders->collection();
545 searchDescription->setBaseCollection( collection );
547 searchDescription->setBaseCollection( Akonadi::Collection() );
549 searchDescription->setRecursive( mUi.mChkSubFolders->isChecked() );
550 new Akonadi::CollectionModifyJob( mFolder,
this );
553 mUi.mStatusLbl->setText( QString() );
556 if ( mCloseRequested )
559 mUi.mLbxMatches->setSortingEnabled(
true );
560 mUi.mLbxMatches->header()->setSortIndicator( mSortColumn, mSortOrder );
562 mUi.mSearchFolderEdt->setEnabled(
true );
566 void SearchWindow::slotStop()
569 mSearchJob->kill( KJob::Quietly );
570 mSearchJob->deleteLater();
577 void SearchWindow::slotClose()
585 mCloseRequested =
true;
587 mSearchJob->kill( KJob::Quietly );
588 mSearchJob->deleteLater();
590 QTimer::singleShot( 0,
this, SLOT(slotClose()) );
592 KDialog::closeEvent( event );
596 void SearchWindow::scheduleRename(
const QString &
text )
598 if ( !text.isEmpty() ) {
599 mRenameTimer.setSingleShot(
true );
600 mRenameTimer.start( 250 );
601 mUi.mSearchFolderOpenBtn->setEnabled(
false );
604 mUi.mSearchFolderOpenBtn->setEnabled( !text.isEmpty() );
608 void SearchWindow::renameSearchFolder()
610 const QString name = mUi.mSearchFolderEdt->text();
611 if ( mFolder.isValid() ) {
612 const QString oldFolderName = mFolder.name();
613 if ( oldFolderName != name ) {
614 mFolder.setName( name );
615 Akonadi::CollectionModifyJob *job =
new Akonadi::CollectionModifyJob( mFolder,
this );
616 job->setProperty(
"oldfoldername", oldFolderName);
617 connect( job, SIGNAL(result(
KJob*)),
618 this, SLOT(slotSearchFolderRenameDone(
KJob*)) );
620 mUi.mSearchFolderOpenBtn->setEnabled(
true );
624 void SearchWindow::slotSearchFolderRenameDone(
KJob *job )
627 if ( job->error() ) {
628 kWarning() <<
"Job failed:" << job->errorText();
629 KMessageBox::information(
this, i18n(
"There was a problem renaming your search folder. "
630 "A common reason for this is that another search folder "
631 "with the same name already exists. Error returned \"%1\".", job->errorText() ) );
632 mUi.mSearchFolderEdt->blockSignals(
true);
633 mUi.mSearchFolderEdt->setText(job->property(
"oldfoldername").toString());
634 mUi.mSearchFolderEdt->blockSignals(
false);
638 void SearchWindow::openSearchFolder()
640 Q_ASSERT( mFolder.isValid() );
641 renameSearchFolder();
646 bool SearchWindow::slotShowMsg(
const Akonadi::Item &item )
648 if ( item.isValid() ) {
655 void SearchWindow::slotViewSelectedMsg()
660 bool SearchWindow::slotViewMsg(
const Akonadi::Item &item )
662 if ( item.isValid() ) {
669 void SearchWindow::slotCurrentChanged(
const Akonadi::Item &item )
671 mUi.mSearchResultOpenBtn->setEnabled( item.isValid() );
674 void SearchWindow::enableGUI()
676 const bool searching = (mSearchJob != 0);
678 mSearchButton->setGuiItem( searching ? mStopSearchGuiItem : mStartSearchGuiItem );
680 disconnect( mSearchButton, SIGNAL(clicked()),
this, SLOT(slotSearch()) );
681 connect( mSearchButton, SIGNAL(clicked()), SLOT(slotStop()) );
683 disconnect( mSearchButton, SIGNAL(clicked()),
this, SLOT(slotStop()) );
684 connect( mSearchButton, SIGNAL(clicked()), SLOT(slotSearch()) );
690 Akonadi::Item::List messages;
692 foreach (
const QModelIndex &index, mUi.mLbxMatches->selectionModel()->selectedRows() ) {
693 const Akonadi::Item item = index.data( Akonadi::ItemModel::ItemRole ).value<Akonadi::Item>();
694 if ( item.isValid() )
695 messages.append( item );
703 return mUi.mLbxMatches->currentIndex().data( Akonadi::ItemModel::ItemRole ).value<Akonadi::Item>();
706 void SearchWindow::updateContextMenuActions()
709 const bool singleActions = (count == 1);
711 mReplyAction->setEnabled( singleActions );
712 mReplyAllAction->setEnabled( singleActions );
713 mReplyListAction->setEnabled( singleActions );
714 mPrintAction->setEnabled( singleActions );
715 mSaveAtchAction->setEnabled( count > 0 );
716 mSaveAsAction->setEnabled( count > 0 );
717 mClearAction->setEnabled( count > 0 );
720 void SearchWindow::slotContextMenuRequested(
const QPoint& )
726 updateContextMenuActions();
729 menu->addAction( mReplyAction );
730 menu->addAction( mReplyAllAction );
731 menu->addAction( mReplyListAction );
732 menu->addAction( mForwardActionMenu );
733 menu->addSeparator();
734 KAction *act = mAkonadiStandardAction->createAction( Akonadi::StandardActionManager::CopyItems );
735 mAkonadiStandardAction->setActionText( Akonadi::StandardActionManager::CopyItems, ki18np(
"Copy Message",
"Copy %1 Messages" ) );
736 menu->addAction( act );
737 act = mAkonadiStandardAction->createAction( Akonadi::StandardActionManager::CutItems );
738 mAkonadiStandardAction->setActionText( Akonadi::StandardActionManager::CutItems, ki18np(
"Cut Message",
"Cut %1 Messages" ) );
739 menu->addAction( act );
740 menu->addAction( mAkonadiStandardAction->createAction( Akonadi::StandardActionManager::CopyItemToMenu ) );
741 menu->addAction( mAkonadiStandardAction->createAction( Akonadi::StandardActionManager::MoveItemToMenu ) );
742 menu->addSeparator();
743 menu->addAction( mSaveAsAction );
744 menu->addAction( mSaveAtchAction );
745 menu->addAction( mPrintAction );
746 menu->addSeparator();
747 menu->addAction( mClearAction );
748 menu->exec( QCursor::pos(), 0 );
753 void SearchWindow::slotClearSelection()
755 mUi.mLbxMatches->clearSelection();
758 void SearchWindow::slotReplyToMsg()
764 void SearchWindow::slotReplyAllToMsg()
770 void SearchWindow::slotReplyListToMsg()
776 void SearchWindow::slotForwardMsg()
782 void SearchWindow::slotForwardAttachedMsg()
788 void SearchWindow::slotSaveMsg()
791 saveCommand->
start();
794 void SearchWindow::slotSaveAttachments()
797 saveCommand->
start();
800 void SearchWindow::slotPrintMsg()
808 SearchPattern p( mSearchPattern );
814 for ( it = pattern.constBegin() ; it != end ; ++it ) {
815 p.append( SearchRule::createInstance( **it ) );
819 mUi.mPatternEdit->setSearchPattern( &mSearchPattern );
824 if ( collection.isValid() ) {
825 QModelIndex idx = Akonadi::EntityTreeModel::modelIndexForCollection(
KMKernel::self()->collectionModel(), collection );
826 if ( idx.isValid() ) {
833 const QModelIndex &parentIndex,
836 const int rowCount = model->rowCount( parentIndex );
837 for (
int row = 0; row < rowCount; ++row ) {
838 const QModelIndex index = model->index( row, 0, parentIndex );
839 if ( model->rowCount( index ) > 0 ) {
842 Akonadi::Collection c = model->data(index, Akonadi::EntityTreeModel::CollectionRole ).value<Akonadi::Collection>();
844 list << c.url( Akonadi::Collection::UrlShort );
848 void SearchWindow::slotDebugQuery()
857 void SearchWindow::slotSelectMultipleFolders()
859 mUi.mChkMultiFolders->setChecked(
true);
860 if (!mSelectMultiCollectionDialog) {
862 Q_FOREACH (
const Akonadi::Collection &col, mCollectionId) {
865 mSelectMultiCollectionDialog =
new MailCommon::SelectMultiCollectionDialog(lst,
this);
867 mSelectMultiCollectionDialog->show();
872 #include "searchwindow.moc"
QByteArray description() const
Akonadi::Item selectedMessage() const
Provides access to the currently selected message.
void setDescription(const QByteArray &desc)
virtual QByteArray text(quint32 serialNumber) const =0
void slotMessageSelected(const Akonadi::Item &)
Opens mail in the internal viewer.
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 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...
~SearchWindow()
Destroys the search window.
void getChildren(const QAbstractItemModel *model, const QModelIndex &parentIndex, KUrl::List &list)
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.
void childCollectionsFromSelectedCollection(const Akonadi::Collection &collection, KUrl::List &list)
QList< Akonadi::Collection::Id > listCollection() const
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.