summaryrefslogtreecommitdiff
authoralwin <alwin>2003-12-27 18:23:23 (UTC)
committer alwin <alwin>2003-12-27 18:23:23 (UTC)
commit7812187f6732eef351e501d993aa664b7e351cbb (patch) (side-by-side diff)
treefe2ed5fc0d8c67983956ecf543a54d2e6355a627
parent583f9d5f33fa055fe8ee612f344d06faae1ef330 (diff)
downloadopie-7812187f6732eef351e501d993aa664b7e351cbb.zip
opie-7812187f6732eef351e501d993aa664b7e351cbb.tar.gz
opie-7812187f6732eef351e501d993aa664b7e351cbb.tar.bz2
folder handling for imap mostly impelemented, context menus for
imap-mail-folders implemented.
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--noncore/net/mail/abstractmail.h9
-rw-r--r--noncore/net/mail/accountview.cpp177
-rw-r--r--noncore/net/mail/accountview.h25
-rw-r--r--noncore/net/mail/imapwrapper.cpp124
-rw-r--r--noncore/net/mail/imapwrapper.h4
-rw-r--r--noncore/net/mail/libmailwrapper/abstractmail.h9
-rw-r--r--noncore/net/mail/libmailwrapper/imapwrapper.cpp124
-rw-r--r--noncore/net/mail/libmailwrapper/imapwrapper.h4
-rw-r--r--noncore/net/mail/libmailwrapper/mailwrapper.cpp4
-rw-r--r--noncore/net/mail/libmailwrapper/mailwrapper.h9
-rw-r--r--noncore/net/mail/mail.pro9
-rw-r--r--noncore/net/mail/mailwrapper.cpp4
-rw-r--r--noncore/net/mail/mailwrapper.h9
-rw-r--r--noncore/net/mail/mainwindow.cpp8
-rw-r--r--noncore/net/mail/newmaildir.cpp34
-rw-r--r--noncore/net/mail/newmaildir.h20
-rw-r--r--noncore/net/mail/newmaildirui.ui100
17 files changed, 619 insertions, 54 deletions
diff --git a/noncore/net/mail/abstractmail.h b/noncore/net/mail/abstractmail.h
index 509b68e..b609aa7 100644
--- a/noncore/net/mail/abstractmail.h
+++ b/noncore/net/mail/abstractmail.h
@@ -27,8 +27,17 @@ public:
virtual void deleteMail(const RecMail&mail)=0;
virtual void answeredMail(const RecMail&mail)=0;
virtual void cleanMimeCache(){};
+ virtual int deleteAllMail(const Folder*){return 1;}
+
+ /* mail box methods */
+ /* parameter is the box to create.
+ * if the implementing subclass has prefixes,
+ * them has to be appended automatic.
+ */
+ virtual int createMbox(const QString&,const Folder*parentfolder=0,const QString& delemiter="/",bool getsubfolder=false){return 0;}
+ virtual int deleteMbox(const Folder*){return 1;}
static AbstractMail* getWrapper(IMAPaccount *a);
static AbstractMail* getWrapper(POP3account *a);
/* mbox only! */
diff --git a/noncore/net/mail/accountview.cpp b/noncore/net/mail/accountview.cpp
index 59e8bc0..8aac14b 100644
--- a/noncore/net/mail/accountview.cpp
+++ b/noncore/net/mail/accountview.cpp
@@ -1,13 +1,15 @@
#include <stdlib.h>
#include "accountview.h"
#include "mailtypes.h"
#include "defines.h"
+#include "newmaildir.h"
+#include <qmessagebox.h>
+#include <qpopupmenu.h>
/**
* POP3 Account stuff
*/
-
POP3viewItem::POP3viewItem( POP3account *a, QListView *parent )
: AccountViewItem( parent )
{
account = a;
@@ -127,9 +129,14 @@ IMAPfolderItem*IMAPviewItem::findSubItem(const QString&path,IMAPfolderItem*start
}
void IMAPviewItem::refresh(QList<RecMail>&)
{
- if (childCount()>0) return;
+ refreshFolders(false);
+}
+
+void IMAPviewItem::refreshFolders(bool force)
+{
+ if (childCount()>0 && force==false) return;
QList<Folder> *folders = wrapper->listFolders();
QListViewItem *child = firstChild();
while ( child ) {
@@ -163,20 +170,63 @@ void IMAPviewItem::refresh(QList<RecMail>&)
IMAPfolderItem*pitem = findSubItem(fname);
if (pitem) {
titem = item;
item = new IMAPfolderItem(it,pitem,pitem->firstChild(),this);
- item->setSelectable(it->may_select());
/* setup the short name */
item->setText(0,it->getDisplayName().right(it->getDisplayName().length()-pos-1));
item = titem;
} else {
item = new IMAPfolderItem( it, this , item );
- item->setSelectable(it->may_select());
}
}
delete folders;
}
+QPopupMenu * IMAPviewItem::getContextMenu()
+{
+ QPopupMenu *m = new QPopupMenu(0);
+ if (m) {
+ m->insertItem(QObject::tr("Refresh folder list","IMAPviewItem"),0);
+ m->insertItem(QObject::tr("Create new folder","IMAPviewItem"),1);
+ m->insertSeparator();
+ m->insertItem(QObject::tr("Disconnect","IMAPviewItem"),2);
+ }
+ return m;
+}
+
+void IMAPviewItem::createNewFolder()
+{
+ Newmdirdlg ndirdlg;
+ ndirdlg.showMaximized();
+ if (ndirdlg.exec()) {
+ QString ndir = ndirdlg.Newdir();
+ bool makesubs = ndirdlg.subpossible();
+ QString delemiter = "/";
+ IMAPfolderItem*item = (IMAPfolderItem*)firstChild();
+ if (item) {
+ delemiter = item->Delemiter();
+ }
+ if (wrapper->createMbox(ndir,0,delemiter,makesubs)) {
+ refreshFolders(true);
+ }
+ }
+}
+
+void IMAPviewItem::contextMenuSelected(int id)
+{
+ qDebug("Id selected: %i",id);
+ switch (id) {
+ case 0:
+ refreshFolders(true);
+ break;
+ case 1:
+ createNewFolder();
+ break;
+ default:
+ break;
+ }
+}
+
RecBody IMAPviewItem::fetchBody(const RecMail&)
{
return RecBody();
}
@@ -211,24 +261,116 @@ IMAPfolderItem::IMAPfolderItem( Folder *folderInit, IMAPfolderItem *parent , QLi
}
setText( 0, folder->getDisplayName() );
}
+const QString& IMAPfolderItem::Delemiter()const
+{
+ return folder->Separator();
+}
+
bool IMAPfolderItem::matchName(const QString&name)const
{
return folder->getDisplayName()==name;
}
void IMAPfolderItem::refresh(QList<RecMail>&target)
{
- if (folder->may_select())
+ if (folder->may_select()) {
imap->getWrapper()->listMessages( folder->getName(),target );
+ } else {
+ target.clear();
+ }
}
RecBody IMAPfolderItem::fetchBody(const RecMail&aMail)
{
return imap->getWrapper()->fetchBody(aMail);
}
+QPopupMenu * IMAPfolderItem::getContextMenu()
+{
+ QPopupMenu *m = new QPopupMenu(0);
+ if (m) {
+ if (folder->may_select()) {
+ m->insertItem(QObject::tr("Refresh header list","IMAPfolderItem"),0);
+ m->insertItem(QObject::tr("Delete all mails","IMAPfolderItem"),1);
+ }
+ if (folder->no_inferior()==false) {
+ m->insertItem(QObject::tr("Create new subfolder","IMAPfolderItem"),2);
+ }
+ if (folder->getDisplayName().lower()!="inbox") {
+ m->insertItem(QObject::tr("Delete folder","IMAPfolderItem"),3);
+ }
+ }
+ return m;
+}
+
+void IMAPfolderItem::deleteAllMails()
+{
+ int yesno = QMessageBox::warning(0,QObject::tr("Delete all mails","IMAPfolderItem"),
+ QObject::tr("<center>Realy delete all mails in box <br>%1</center>","IMAPfolderItem").arg(folder->getDisplayName()),
+ QObject::tr("Yes","IMAPfolderItem"),
+ QObject::tr("No","IMAPfolderItem"),QString::null,1,1);
+ qDebug("Auswahl: %i",yesno);
+ if (yesno == 0) {
+ if (imap->getWrapper()->deleteAllMail(folder)) {
+ AccountView * view = (AccountView*)listView();
+ if (view) view->refreshCurrent();
+ }
+ }
+}
+
+void IMAPfolderItem::createNewFolder()
+{
+ Newmdirdlg ndirdlg;
+ ndirdlg.showMaximized();
+ if (ndirdlg.exec()) {
+ QString ndir = ndirdlg.Newdir();
+ bool makesubs = ndirdlg.subpossible();
+ QString delemiter = Delemiter();
+ if (imap->wrapper->createMbox(ndir,folder,delemiter,makesubs)) {
+ imap->refreshFolders(true);
+ }
+ }
+}
+
+void IMAPfolderItem::deleteFolder()
+{
+ int yesno = QMessageBox::warning(0,QObject::tr("Delete folder","IMAPfolderItem"),
+ QObject::tr("<center>Realy delete folder <br><b>%1</b><br>and all if it content?</center>","IMAPfolderItem").arg(folder->getDisplayName()),
+ QObject::tr("Yes","IMAPfolderItem"),
+ QObject::tr("No","IMAPfolderItem"),QString::null,1,1);
+ qDebug("Auswahl: %i",yesno);
+ if (yesno == 0) {
+ if (imap->getWrapper()->deleteMbox(folder)) {
+ /* be carefull - after that this object is destroyd so don't call
+ * any member of it after that call!!*/
+ imap->refreshFolders(true);
+ }
+ }
+}
+
+void IMAPfolderItem::contextMenuSelected(int id)
+{
+ qDebug("Selected id: %i",id);
+ AccountView * view = (AccountView*)listView();
+ switch(id) {
+ case 0:
+ view->refreshCurrent();
+ break;
+ case 1:
+ deleteAllMails();
+ break;
+ case 2:
+ createNewFolder();
+ break;
+ case 3:
+ deleteFolder();
+ break;
+ default:
+ break;
+ }
+}
/**
* Generic stuff
*/
@@ -237,11 +379,34 @@ AccountView::AccountView( QWidget *parent, const char *name, WFlags flags )
: QListView( parent, name, flags )
{
connect( this, SIGNAL( selectionChanged( QListViewItem * ) ),
SLOT( refresh( QListViewItem * ) ) );
+ connect( this, SIGNAL( mouseButtonPressed(int, QListViewItem *,const QPoint&,int ) ),this,
+ SLOT( slotHold( int, QListViewItem *,const QPoint&,int ) ) );
+
setSorting(0);
}
+void AccountView::slotContextMenu(int id)
+{
+ AccountViewItem *view = static_cast<AccountViewItem *>(currentItem());
+ if (!view) return;
+ view->contextMenuSelected(id);
+}
+
+void AccountView::slotHold(int button, QListViewItem * item,const QPoint&,int)
+{
+ if (button==1) {return;}
+ if (!item) return;
+ AccountViewItem *view = static_cast<AccountViewItem *>(item);
+ QPopupMenu*m = view->getContextMenu();
+ if (!m) return;
+ connect(m,SIGNAL(activated(int)),this,SLOT(slotContextMenu(int)));
+ m->setFocus();
+ m->exec( QPoint( QCursor::pos().x(), QCursor::pos().y()) );
+ delete m;
+}
+
void AccountView::populate( QList<Account> list )
{
clear();
@@ -276,8 +441,9 @@ void AccountView::refresh(QListViewItem *item) {
}
void AccountView::refreshCurrent()
{
+ m_currentItem = currentItem();
if ( !m_currentItem ) return;
QList<RecMail> headerlist;
headerlist.setAutoDelete(true);
AccountViewItem *view = static_cast<AccountViewItem *>(m_currentItem);
@@ -377,5 +543,4 @@ void MBOXfolderItem::refresh(QList<RecMail>&target)
RecBody MBOXfolderItem::fetchBody(const RecMail&aMail)
{
return mbox->getWrapper()->fetchBody(aMail);
}
-
diff --git a/noncore/net/mail/accountview.h b/noncore/net/mail/accountview.h
index 35499ac..e7fe038 100644
--- a/noncore/net/mail/accountview.h
+++ b/noncore/net/mail/accountview.h
@@ -10,8 +10,9 @@
class POP3wrapper;
class RecMail;
class RecBody;
+class QPopupMenu;
class AccountViewItem : public QListViewItem
{
@@ -20,8 +21,10 @@ public:
AccountViewItem( QListViewItem *parent) : QListViewItem( parent) {}
AccountViewItem( QListViewItem *parent , QListViewItem*after ) : QListViewItem( parent,after ) {}
virtual void refresh(QList<RecMail>&)=0;
virtual RecBody fetchBody(const RecMail&)=0;
+ virtual QPopupMenu * getContextMenu(){return 0;};
+ virtual void contextMenuSelected(int){}
};
class POP3viewItem : public AccountViewItem
{
@@ -54,18 +57,22 @@ private:
class IMAPfolderItem;
class IMAPviewItem : public AccountViewItem
{
-
+ friend class IMAPfolderItem;
public:
IMAPviewItem( IMAPaccount *a, QListView *parent );
~IMAPviewItem();
virtual void refresh(QList<RecMail>&);
virtual RecBody fetchBody(const RecMail&);
AbstractMail *getWrapper();
+ virtual QPopupMenu * getContextMenu();
+ virtual void contextMenuSelected(int);
protected:
IMAPfolderItem*findSubItem(const QString&path,IMAPfolderItem*start=0);
+ virtual void refreshFolders(bool force=false);
+ virtual void createNewFolder();
private:
IMAPaccount *account;
AbstractMail *wrapper;
@@ -80,8 +87,16 @@ public:
~IMAPfolderItem();
virtual void refresh(QList<RecMail>&);
virtual RecBody fetchBody(const RecMail&);
bool matchName(const QString&name)const;
+ virtual void deleteAllMails();
+ virtual QPopupMenu * getContextMenu();
+ virtual void contextMenuSelected(int);
+ virtual const QString& Delemiter()const;
+protected:
+ virtual void createNewFolder();
+ virtual void deleteFolder();
+
private:
Folder *folder;
IMAPviewItem *imap;
};
@@ -125,11 +140,13 @@ public:
void populate( QList<Account> list );
RecBody fetchBody(const RecMail&aMail);
public slots:
- void refreshAll();
- void refresh(QListViewItem *item);
- void refreshCurrent();
+ virtual void refreshAll();
+ virtual void refresh(QListViewItem *item);
+ virtual void refreshCurrent();
+ virtual void slotHold(int, QListViewItem *,const QPoint&,int);
+ virtual void slotContextMenu(int id);
signals:
void refreshMailview(QList<RecMail>*);
diff --git a/noncore/net/mail/imapwrapper.cpp b/noncore/net/mail/imapwrapper.cpp
index ab20249..406c57c 100644
--- a/noncore/net/mail/imapwrapper.cpp
+++ b/noncore/net/mail/imapwrapper.cpp
@@ -1,8 +1,7 @@
-
#include <stdlib.h>
-
#include <libetpan/libetpan.h>
+#include <qpe/global.h>
#include "imapwrapper.h"
#include "mailtypes.h"
#include "logindialog.h"
@@ -70,18 +69,18 @@ void IMAPwrapper::login()
if ( err != MAILIMAP_NO_ERROR &&
err != MAILIMAP_NO_ERROR_AUTHENTICATED &&
err != MAILIMAP_NO_ERROR_NON_AUTHENTICATED ) {
- qDebug("error connecting server: %s",m_imap->imap_response);
+ Global::statusMessage(tr("error connecting imap server: %1").arg(m_imap->imap_response));
mailimap_free( m_imap );
m_imap = 0;
return;
}
/* login */
err = mailimap_login_simple( m_imap, (char*)user, (char*)pass );
if ( err != MAILIMAP_NO_ERROR ) {
- qDebug("error logging in imap: %s",m_imap->imap_response);
+ Global::statusMessage(tr("error logging in imap server: %1").arg(m_imap->imap_response));
err = mailimap_close( m_imap );
mailimap_free( m_imap );
m_imap = 0;
}
@@ -114,17 +113,19 @@ void IMAPwrapper::listMessages(const QString&mailbox,QList<RecMail> &target )
}
/* select mailbox READONLY for operations */
err = mailimap_examine( m_imap, (char*)mb);
if ( err != MAILIMAP_NO_ERROR ) {
- qDebug("error selecting mailbox: %s",m_imap->imap_response);
+ Global::statusMessage(tr("error selecting mailbox: %1").arg(m_imap->imap_response));
return;
}
int last = m_imap->imap_selection_info->sel_exists;
if (last == 0) {
- qDebug("mailbox has no mails");
+ Global::statusMessage(tr("Mailbox has no mails"));
return;
+ } else {
+ Global::statusMessage(tr("Mailbox has %1 mails").arg(last));
}
/* the range has to start at 1!!! not with 0!!!! */
set = mailimap_set_new_interval( 1, last );
@@ -154,9 +155,9 @@ void IMAPwrapper::listMessages(const QString&mailbox,QList<RecMail> &target )
target.append(m);
}
}
} else {
- qDebug("Error fetching headers: %s",m_imap->imap_response);
+ Global::statusMessage(tr("Error fetching headers: %1").arg(m_imap->imap_response));
}
if (result) mailimap_fetch_list_free(result);
}
@@ -165,8 +166,10 @@ QList<Folder>* IMAPwrapper::listFolders()
const char *path, *mask;
int err = MAILIMAP_NO_ERROR;
clist *result = 0;
clistcell *current = 0;
+ clistcell*cur_flag = 0;
+ mailimap_mbx_list_flags*bflags = 0;
QList<Folder> * folders = new QList<Folder>();
folders->setAutoDelete( false );
login();
@@ -183,18 +186,29 @@ QList<Folder>* IMAPwrapper::listFolders()
mask = "INBOX" ;
mailimap_mailbox_list *list;
err = mailimap_list( m_imap, (char*)"", (char*)mask, &result );
QString del;
+ bool selectable = true;
+ bool no_inferiors = false;
if ( err == MAILIMAP_NO_ERROR ) {
current = result->first;
for ( int i = result->count; i > 0; i-- ) {
list = (mailimap_mailbox_list *) current->data;
// it is better use the deep copy mechanism of qt itself
// instead of using strdup!
temp = list->mb_name;
del = list->mb_delimiter;
- folders->append( new IMAPFolder(temp,del,true,account->getPrefix()));
current = current->next;
+ if ( (bflags = list->mb_flag) ) {
+ selectable = !(bflags->mbf_type==MAILIMAP_MBX_LIST_FLAGS_SFLAG&&
+ bflags->mbf_sflag==MAILIMAP_MBX_LIST_SFLAG_NOSELECT);
+ for(cur_flag=clist_begin(bflags->mbf_oflags);cur_flag;cur_flag=clist_next(cur_flag)) {
+ if ( ((mailimap_mbx_list_oflag*)cur_flag->data)->of_type==MAILIMAP_MBX_LIST_OFLAG_NOINFERIORS) {
+ no_inferiors = true;
+ }
+ }
+ }
+ folders->append( new IMAPFolder(temp,del,selectable,no_inferiors,account->getPrefix()));
}
} else {
qDebug("error fetching folders: %s",m_imap->imap_response);
}
@@ -206,14 +220,13 @@ QList<Folder>* IMAPwrapper::listFolders()
mask = "*" ;
path = account->getPrefix().latin1();
if (!path) path = "";
qDebug(path);
- bool selectable = true;
- mailimap_mbx_list_flags*bflags;
err = mailimap_list( m_imap, (char*)path, (char*)mask, &result );
if ( err == MAILIMAP_NO_ERROR ) {
current = result->first;
for ( current=clist_begin(result);current!=NULL;current=clist_next(current)) {
+ no_inferiors = false;
list = (mailimap_mailbox_list *) current->data;
// it is better use the deep copy mechanism of qt itself
// instead of using strdup!
temp = list->mb_name;
@@ -223,11 +236,16 @@ QList<Folder>* IMAPwrapper::listFolders()
continue;
if ( (bflags = list->mb_flag) ) {
selectable = !(bflags->mbf_type==MAILIMAP_MBX_LIST_FLAGS_SFLAG&&
bflags->mbf_sflag==MAILIMAP_MBX_LIST_SFLAG_NOSELECT);
+ for(cur_flag=clist_begin(bflags->mbf_oflags);cur_flag;cur_flag=clist_next(cur_flag)) {
+ if ( ((mailimap_mbx_list_oflag*)cur_flag->data)->of_type==MAILIMAP_MBX_LIST_OFLAG_NOINFERIORS) {
+ no_inferiors = true;
+ }
+ }
}
del = list->mb_delimiter;
- folders->append(new IMAPFolder(temp,del,selectable,account->getPrefix()));
+ folders->append(new IMAPFolder(temp,del,selectable,no_inferiors,account->getPrefix()));
}
} else {
qDebug("error fetching folders %s",m_imap->imap_response);
}
@@ -817,4 +835,88 @@ encodedString* IMAPwrapper::fetchDecodedPart(const RecMail&mail,const RecPart&pa
encodedString* IMAPwrapper::fetchRawPart(const RecMail&mail,const RecPart&part)
{
return fetchRawPart(mail,part.Positionlist(),false);
}
+
+int IMAPwrapper::deleteAllMail(const Folder*folder)
+{
+ login();
+ if (!m_imap) {
+ return 0;
+ }
+ mailimap_flag_list*flist;
+ mailimap_set *set;
+ mailimap_store_att_flags * store_flags;
+ int err = mailimap_select( m_imap, folder->getName().latin1());
+ if ( err != MAILIMAP_NO_ERROR ) {
+ Global::statusMessage(tr("error selecting mailbox: %1").arg(m_imap->imap_response));
+ return 0;
+ }
+ int last = m_imap->imap_selection_info->sel_exists;
+ if (last == 0) {
+ Global::statusMessage(tr("Mailbox has no mails!"));
+ return 0;
+ }
+ flist = mailimap_flag_list_new_empty();
+ mailimap_flag_list_add(flist,mailimap_flag_new_deleted());
+ store_flags = mailimap_store_att_flags_new_set_flags(flist);
+ set = mailimap_set_new_interval( 1, last );
+ err = mailimap_store(m_imap,set,store_flags);
+ mailimap_set_free( set );
+ mailimap_store_att_flags_free(store_flags);
+ if (err != MAILIMAP_NO_ERROR) {
+ Global::statusMessage(tr("error deleting mail: %s").arg(m_imap->imap_response));
+ return 0;
+ }
+ qDebug("deleting mail: %s",m_imap->imap_response);
+ /* should we realy do that at this moment? */
+ err = mailimap_expunge(m_imap);
+ if (err != MAILIMAP_NO_ERROR) {
+ Global::statusMessage(tr("error deleting mail: %s").arg(m_imap->imap_response));
+ return 0;
+ }
+ qDebug("Delete successfull %s",m_imap->imap_response);
+ return 1;
+}
+
+int IMAPwrapper::createMbox(const QString&folder,const Folder*parentfolder,const QString& delemiter,bool getsubfolder)
+{
+ if (folder.length()==0) return 0;
+ login();
+ if (!m_imap) {return 0;}
+ QString pre = account->getPrefix();
+ if (delemiter.length()>0 && pre.findRev(delemiter)!=pre.length()-1) {
+ pre+=delemiter;
+ }
+ if (parentfolder) {
+ pre += parentfolder->getDisplayName()+delemiter;
+ }
+ pre+=folder;
+ if (getsubfolder) {
+ if (delemiter.length()>0) {
+ pre+=delemiter;
+ } else {
+ Global::statusMessage(tr("Cannot create folder %1 for holding subfolders").arg(pre));
+ return 0;
+ }
+ }
+ qDebug("Creating %s",pre.latin1());
+ int res = mailimap_create(m_imap,pre.latin1());
+ if (res != MAILIMAP_NO_ERROR) {
+ Global::statusMessage(tr("%1").arg(m_imap->imap_response));
+ return 0;
+ }
+ return 1;
+}
+
+int IMAPwrapper::deleteMbox(const Folder*folder)
+{
+ if (!folder) return 0;
+ login();
+ if (!m_imap) {return 0;}
+ int res = mailimap_delete(m_imap,folder->getName());
+ if (res != MAILIMAP_NO_ERROR) {
+ Global::statusMessage(tr("%1").arg(m_imap->imap_response));
+ return 0;
+ }
+ return 1;
+}
diff --git a/noncore/net/mail/imapwrapper.h b/noncore/net/mail/imapwrapper.h
index f046297..9b20288 100644
--- a/noncore/net/mail/imapwrapper.h
+++ b/noncore/net/mail/imapwrapper.h
@@ -26,14 +26,18 @@ public:
virtual void listMessages(const QString & mailbox,QList<RecMail>&target );
virtual void deleteMail(const RecMail&mail);
virtual void answeredMail(const RecMail&mail);
+ virtual int deleteAllMail(const Folder*folder);
virtual RecBody fetchBody(const RecMail&mail);
virtual QString fetchTextPart(const RecMail&mail,const RecPart&part);
virtual encodedString* fetchDecodedPart(const RecMail&mail,const RecPart&part);
virtual encodedString* fetchRawPart(const RecMail&mail,const RecPart&part);
+ virtual int createMbox(const QString&,const Folder*parentfolder=0,const QString& delemiter="/",bool getsubfolder=false);
+ virtual int deleteMbox(const Folder*folder);
+
static void imap_progress( size_t current, size_t maximum );
protected:
RecMail*parse_list_result(mailimap_msg_att*);
diff --git a/noncore/net/mail/libmailwrapper/abstractmail.h b/noncore/net/mail/libmailwrapper/abstractmail.h
index 509b68e..b609aa7 100644
--- a/noncore/net/mail/libmailwrapper/abstractmail.h
+++ b/noncore/net/mail/libmailwrapper/abstractmail.h
@@ -27,8 +27,17 @@ public:
virtual void deleteMail(const RecMail&mail)=0;
virtual void answeredMail(const RecMail&mail)=0;
virtual void cleanMimeCache(){};
+ virtual int deleteAllMail(const Folder*){return 1;}
+
+ /* mail box methods */
+ /* parameter is the box to create.
+ * if the implementing subclass has prefixes,
+ * them has to be appended automatic.
+ */
+ virtual int createMbox(const QString&,const Folder*parentfolder=0,const QString& delemiter="/",bool getsubfolder=false){return 0;}
+ virtual int deleteMbox(const Folder*){return 1;}
static AbstractMail* getWrapper(IMAPaccount *a);
static AbstractMail* getWrapper(POP3account *a);
/* mbox only! */
diff --git a/noncore/net/mail/libmailwrapper/imapwrapper.cpp b/noncore/net/mail/libmailwrapper/imapwrapper.cpp
index ab20249..406c57c 100644
--- a/noncore/net/mail/libmailwrapper/imapwrapper.cpp
+++ b/noncore/net/mail/libmailwrapper/imapwrapper.cpp
@@ -1,8 +1,7 @@
-
#include <stdlib.h>
-
#include <libetpan/libetpan.h>
+#include <qpe/global.h>
#include "imapwrapper.h"
#include "mailtypes.h"
#include "logindialog.h"
@@ -70,18 +69,18 @@ void IMAPwrapper::login()
if ( err != MAILIMAP_NO_ERROR &&
err != MAILIMAP_NO_ERROR_AUTHENTICATED &&
err != MAILIMAP_NO_ERROR_NON_AUTHENTICATED ) {
- qDebug("error connecting server: %s",m_imap->imap_response);
+ Global::statusMessage(tr("error connecting imap server: %1").arg(m_imap->imap_response));
mailimap_free( m_imap );
m_imap = 0;
return;
}
/* login */
err = mailimap_login_simple( m_imap, (char*)user, (char*)pass );
if ( err != MAILIMAP_NO_ERROR ) {
- qDebug("error logging in imap: %s",m_imap->imap_response);
+ Global::statusMessage(tr("error logging in imap server: %1").arg(m_imap->imap_response));
err = mailimap_close( m_imap );
mailimap_free( m_imap );
m_imap = 0;
}
@@ -114,17 +113,19 @@ void IMAPwrapper::listMessages(const QString&mailbox,QList<RecMail> &target )
}
/* select mailbox READONLY for operations */
err = mailimap_examine( m_imap, (char*)mb);
if ( err != MAILIMAP_NO_ERROR ) {
- qDebug("error selecting mailbox: %s",m_imap->imap_response);
+ Global::statusMessage(tr("error selecting mailbox: %1").arg(m_imap->imap_response));
return;
}
int last = m_imap->imap_selection_info->sel_exists;
if (last == 0) {
- qDebug("mailbox has no mails");
+ Global::statusMessage(tr("Mailbox has no mails"));
return;
+ } else {
+ Global::statusMessage(tr("Mailbox has %1 mails").arg(last));
}
/* the range has to start at 1!!! not with 0!!!! */
set = mailimap_set_new_interval( 1, last );
@@ -154,9 +155,9 @@ void IMAPwrapper::listMessages(const QString&mailbox,QList<RecMail> &target )
target.append(m);
}
}
} else {
- qDebug("Error fetching headers: %s",m_imap->imap_response);
+ Global::statusMessage(tr("Error fetching headers: %1").arg(m_imap->imap_response));
}
if (result) mailimap_fetch_list_free(result);
}
@@ -165,8 +166,10 @@ QList<Folder>* IMAPwrapper::listFolders()
const char *path, *mask;
int err = MAILIMAP_NO_ERROR;
clist *result = 0;
clistcell *current = 0;
+ clistcell*cur_flag = 0;
+ mailimap_mbx_list_flags*bflags = 0;
QList<Folder> * folders = new QList<Folder>();
folders->setAutoDelete( false );
login();
@@ -183,18 +186,29 @@ QList<Folder>* IMAPwrapper::listFolders()
mask = "INBOX" ;
mailimap_mailbox_list *list;
err = mailimap_list( m_imap, (char*)"", (char*)mask, &result );
QString del;
+ bool selectable = true;
+ bool no_inferiors = false;
if ( err == MAILIMAP_NO_ERROR ) {
current = result->first;
for ( int i = result->count; i > 0; i-- ) {
list = (mailimap_mailbox_list *) current->data;
// it is better use the deep copy mechanism of qt itself
// instead of using strdup!
temp = list->mb_name;
del = list->mb_delimiter;
- folders->append( new IMAPFolder(temp,del,true,account->getPrefix()));
current = current->next;
+ if ( (bflags = list->mb_flag) ) {
+ selectable = !(bflags->mbf_type==MAILIMAP_MBX_LIST_FLAGS_SFLAG&&
+ bflags->mbf_sflag==MAILIMAP_MBX_LIST_SFLAG_NOSELECT);
+ for(cur_flag=clist_begin(bflags->mbf_oflags);cur_flag;cur_flag=clist_next(cur_flag)) {
+ if ( ((mailimap_mbx_list_oflag*)cur_flag->data)->of_type==MAILIMAP_MBX_LIST_OFLAG_NOINFERIORS) {
+ no_inferiors = true;
+ }
+ }
+ }
+ folders->append( new IMAPFolder(temp,del,selectable,no_inferiors,account->getPrefix()));
}
} else {
qDebug("error fetching folders: %s",m_imap->imap_response);
}
@@ -206,14 +220,13 @@ QList<Folder>* IMAPwrapper::listFolders()
mask = "*" ;
path = account->getPrefix().latin1();
if (!path) path = "";
qDebug(path);
- bool selectable = true;
- mailimap_mbx_list_flags*bflags;
err = mailimap_list( m_imap, (char*)path, (char*)mask, &result );
if ( err == MAILIMAP_NO_ERROR ) {
current = result->first;
for ( current=clist_begin(result);current!=NULL;current=clist_next(current)) {
+ no_inferiors = false;
list = (mailimap_mailbox_list *) current->data;
// it is better use the deep copy mechanism of qt itself
// instead of using strdup!
temp = list->mb_name;
@@ -223,11 +236,16 @@ QList<Folder>* IMAPwrapper::listFolders()
continue;
if ( (bflags = list->mb_flag) ) {
selectable = !(bflags->mbf_type==MAILIMAP_MBX_LIST_FLAGS_SFLAG&&
bflags->mbf_sflag==MAILIMAP_MBX_LIST_SFLAG_NOSELECT);
+ for(cur_flag=clist_begin(bflags->mbf_oflags);cur_flag;cur_flag=clist_next(cur_flag)) {
+ if ( ((mailimap_mbx_list_oflag*)cur_flag->data)->of_type==MAILIMAP_MBX_LIST_OFLAG_NOINFERIORS) {
+ no_inferiors = true;
+ }
+ }
}
del = list->mb_delimiter;
- folders->append(new IMAPFolder(temp,del,selectable,account->getPrefix()));
+ folders->append(new IMAPFolder(temp,del,selectable,no_inferiors,account->getPrefix()));
}
} else {
qDebug("error fetching folders %s",m_imap->imap_response);
}
@@ -817,4 +835,88 @@ encodedString* IMAPwrapper::fetchDecodedPart(const RecMail&mail,const RecPart&pa
encodedString* IMAPwrapper::fetchRawPart(const RecMail&mail,const RecPart&part)
{
return fetchRawPart(mail,part.Positionlist(),false);
}
+
+int IMAPwrapper::deleteAllMail(const Folder*folder)
+{
+ login();
+ if (!m_imap) {
+ return 0;
+ }
+ mailimap_flag_list*flist;
+ mailimap_set *set;
+ mailimap_store_att_flags * store_flags;
+ int err = mailimap_select( m_imap, folder->getName().latin1());
+ if ( err != MAILIMAP_NO_ERROR ) {
+ Global::statusMessage(tr("error selecting mailbox: %1").arg(m_imap->imap_response));
+ return 0;
+ }
+ int last = m_imap->imap_selection_info->sel_exists;
+ if (last == 0) {
+ Global::statusMessage(tr("Mailbox has no mails!"));
+ return 0;
+ }
+ flist = mailimap_flag_list_new_empty();
+ mailimap_flag_list_add(flist,mailimap_flag_new_deleted());
+ store_flags = mailimap_store_att_flags_new_set_flags(flist);
+ set = mailimap_set_new_interval( 1, last );
+ err = mailimap_store(m_imap,set,store_flags);
+ mailimap_set_free( set );
+ mailimap_store_att_flags_free(store_flags);
+ if (err != MAILIMAP_NO_ERROR) {
+ Global::statusMessage(tr("error deleting mail: %s").arg(m_imap->imap_response));
+ return 0;
+ }
+ qDebug("deleting mail: %s",m_imap->imap_response);
+ /* should we realy do that at this moment? */
+ err = mailimap_expunge(m_imap);
+ if (err != MAILIMAP_NO_ERROR) {
+ Global::statusMessage(tr("error deleting mail: %s").arg(m_imap->imap_response));
+ return 0;
+ }
+ qDebug("Delete successfull %s",m_imap->imap_response);
+ return 1;
+}
+
+int IMAPwrapper::createMbox(const QString&folder,const Folder*parentfolder,const QString& delemiter,bool getsubfolder)
+{
+ if (folder.length()==0) return 0;
+ login();
+ if (!m_imap) {return 0;}
+ QString pre = account->getPrefix();
+ if (delemiter.length()>0 && pre.findRev(delemiter)!=pre.length()-1) {
+ pre+=delemiter;
+ }
+ if (parentfolder) {
+ pre += parentfolder->getDisplayName()+delemiter;
+ }
+ pre+=folder;
+ if (getsubfolder) {
+ if (delemiter.length()>0) {
+ pre+=delemiter;
+ } else {
+ Global::statusMessage(tr("Cannot create folder %1 for holding subfolders").arg(pre));
+ return 0;
+ }
+ }
+ qDebug("Creating %s",pre.latin1());
+ int res = mailimap_create(m_imap,pre.latin1());
+ if (res != MAILIMAP_NO_ERROR) {
+ Global::statusMessage(tr("%1").arg(m_imap->imap_response));
+ return 0;
+ }
+ return 1;
+}
+
+int IMAPwrapper::deleteMbox(const Folder*folder)
+{
+ if (!folder) return 0;
+ login();
+ if (!m_imap) {return 0;}
+ int res = mailimap_delete(m_imap,folder->getName());
+ if (res != MAILIMAP_NO_ERROR) {
+ Global::statusMessage(tr("%1").arg(m_imap->imap_response));
+ return 0;
+ }
+ return 1;
+}
diff --git a/noncore/net/mail/libmailwrapper/imapwrapper.h b/noncore/net/mail/libmailwrapper/imapwrapper.h
index f046297..9b20288 100644
--- a/noncore/net/mail/libmailwrapper/imapwrapper.h
+++ b/noncore/net/mail/libmailwrapper/imapwrapper.h
@@ -26,14 +26,18 @@ public:
virtual void listMessages(const QString & mailbox,QList<RecMail>&target );
virtual void deleteMail(const RecMail&mail);
virtual void answeredMail(const RecMail&mail);
+ virtual int deleteAllMail(const Folder*folder);
virtual RecBody fetchBody(const RecMail&mail);
virtual QString fetchTextPart(const RecMail&mail,const RecPart&part);
virtual encodedString* fetchDecodedPart(const RecMail&mail,const RecPart&part);
virtual encodedString* fetchRawPart(const RecMail&mail,const RecPart&part);
+ virtual int createMbox(const QString&,const Folder*parentfolder=0,const QString& delemiter="/",bool getsubfolder=false);
+ virtual int deleteMbox(const Folder*folder);
+
static void imap_progress( size_t current, size_t maximum );
protected:
RecMail*parse_list_result(mailimap_msg_att*);
diff --git a/noncore/net/mail/libmailwrapper/mailwrapper.cpp b/noncore/net/mail/libmailwrapper/mailwrapper.cpp
index 6479783..9398823 100644
--- a/noncore/net/mail/libmailwrapper/mailwrapper.cpp
+++ b/noncore/net/mail/libmailwrapper/mailwrapper.cpp
@@ -27,10 +27,10 @@ const QString& Folder::Separator()const
{
return separator;
}
-IMAPFolder::IMAPFolder(const QString&name,const QString&sep, bool select,const QString&prefix )
- : Folder( name,sep ),m_MaySelect(select)
+IMAPFolder::IMAPFolder(const QString&name,const QString&sep, bool select,bool no_inf, const QString&prefix )
+ : Folder( name,sep ),m_MaySelect(select),m_NoInferior(no_inf)
{
// Decode IMAP foldername
nameDisplay = IMAPFolder::decodeFolderName( name );
qDebug( "folder " + name + " - displayed as " + nameDisplay );
diff --git a/noncore/net/mail/libmailwrapper/mailwrapper.h b/noncore/net/mail/libmailwrapper/mailwrapper.h
index 8fd886f..a60777d 100644
--- a/noncore/net/mail/libmailwrapper/mailwrapper.h
+++ b/noncore/net/mail/libmailwrapper/mailwrapper.h
@@ -68,9 +68,10 @@ class Folder : public QObject
public:
Folder( const QString&init_name,const QString&sep );
const QString&getDisplayName()const { return nameDisplay; }
const QString&getName()const { return name; }
- virtual bool may_select()const{return true;};
+ virtual bool may_select()const{return true;}
+ virtual bool no_inferior()const{return true;}
const QString&Separator()const;
protected:
QString nameDisplay, name, separator;
@@ -79,13 +80,13 @@ protected:
class IMAPFolder : public Folder
{
public:
- IMAPFolder(const QString&name, const QString&sep, bool select=true,const QString&prefix="" );
+ IMAPFolder(const QString&name, const QString&sep, bool select=true,bool noinf=false,const QString&prefix="" );
virtual bool may_select()const{return m_MaySelect;}
+ virtual bool no_inferior()const{return m_NoInferior;}
private:
static QString decodeFolderName( const QString &name );
- bool m_MaySelect;
-
+ bool m_MaySelect,m_NoInferior;
};
#endif
diff --git a/noncore/net/mail/mail.pro b/noncore/net/mail/mail.pro
index ea5fb58..2c15a7b 100644
--- a/noncore/net/mail/mail.pro
+++ b/noncore/net/mail/mail.pro
@@ -20,9 +20,10 @@ HEADERS = defines.h \
statuswidget.h \
smtpwrapper.h \
genericwrapper.h \
mboxwrapper.h \
- sendmailprogress.h
+ sendmailprogress.h \
+ newmaildir.h
SOURCES = main.cpp \
opiemail.cpp \
mainwindow.cpp \
@@ -43,9 +44,10 @@ SOURCES = main.cpp \
statuswidget.cpp \
smtpwrapper.cpp \
genericwrapper.cpp \
mboxwrapper.cpp \
- sendmailprogress.cpp
+ sendmailprogress.cpp \
+ newmaildir.cpp
INTERFACES = editaccountsui.ui \
selectmailtypeui.ui \
imapconfigui.ui \
@@ -56,9 +58,10 @@ INTERFACES = editaccountsui.ui \
logindialogui.ui \
composemailui.ui \
settingsdialogui.ui \
statuswidgetui.ui \
- sendmailprogressui.ui
+ sendmailprogressui.ui \
+ newmaildirui.ui
INCLUDEPATH += $(OPIEDIR)/include
CONFTEST = $$system( echo $CONFIG_TARGET_MACOSX )
diff --git a/noncore/net/mail/mailwrapper.cpp b/noncore/net/mail/mailwrapper.cpp
index 6479783..9398823 100644
--- a/noncore/net/mail/mailwrapper.cpp
+++ b/noncore/net/mail/mailwrapper.cpp
@@ -27,10 +27,10 @@ const QString& Folder::Separator()const
{
return separator;
}
-IMAPFolder::IMAPFolder(const QString&name,const QString&sep, bool select,const QString&prefix )
- : Folder( name,sep ),m_MaySelect(select)
+IMAPFolder::IMAPFolder(const QString&name,const QString&sep, bool select,bool no_inf, const QString&prefix )
+ : Folder( name,sep ),m_MaySelect(select),m_NoInferior(no_inf)
{
// Decode IMAP foldername
nameDisplay = IMAPFolder::decodeFolderName( name );
qDebug( "folder " + name + " - displayed as " + nameDisplay );
diff --git a/noncore/net/mail/mailwrapper.h b/noncore/net/mail/mailwrapper.h
index 8fd886f..a60777d 100644
--- a/noncore/net/mail/mailwrapper.h
+++ b/noncore/net/mail/mailwrapper.h
@@ -68,9 +68,10 @@ class Folder : public QObject
public:
Folder( const QString&init_name,const QString&sep );
const QString&getDisplayName()const { return nameDisplay; }
const QString&getName()const { return name; }
- virtual bool may_select()const{return true;};
+ virtual bool may_select()const{return true;}
+ virtual bool no_inferior()const{return true;}
const QString&Separator()const;
protected:
QString nameDisplay, name, separator;
@@ -79,13 +80,13 @@ protected:
class IMAPFolder : public Folder
{
public:
- IMAPFolder(const QString&name, const QString&sep, bool select=true,const QString&prefix="" );
+ IMAPFolder(const QString&name, const QString&sep, bool select=true,bool noinf=false,const QString&prefix="" );
virtual bool may_select()const{return m_MaySelect;}
+ virtual bool no_inferior()const{return m_NoInferior;}
private:
static QString decodeFolderName( const QString &name );
- bool m_MaySelect;
-
+ bool m_MaySelect,m_NoInferior;
};
#endif
diff --git a/noncore/net/mail/mainwindow.cpp b/noncore/net/mail/mainwindow.cpp
index dc8c188..cf4cbe8 100644
--- a/noncore/net/mail/mainwindow.cpp
+++ b/noncore/net/mail/mainwindow.cpp
@@ -116,26 +116,20 @@ MainWindow::MainWindow( QWidget *parent, const char *name, WFlags flags )
layout->addWidget( mailView );
layout->setStretchFactor( folderView, 1 );
layout->setStretchFactor( mailView, 2 );
-
slotAdjustLayout();
QPEApplication::setStylusOperation( mailView->viewport(),QPEApplication::RightOnHold);
+ QPEApplication::setStylusOperation( folderView->viewport(),QPEApplication::RightOnHold);
connect( mailView, SIGNAL( mouseButtonClicked(int, QListViewItem *,const QPoint&,int ) ),this,
SLOT( mailLeftClicked( int, QListViewItem *,const QPoint&,int ) ) );
-
connect( mailView, SIGNAL( mouseButtonPressed(int, QListViewItem *,const QPoint&,int ) ),this,
SLOT( mailHold( int, QListViewItem *,const QPoint&,int ) ) );
-#if 0
- connect( mailView, SIGNAL( rightButtonClicked( QListViewItem *,const QPoint&,int ) ),this,
- SLOT( mailHold(QListViewItem *,const QPoint&,int) ));
-#endif
connect(folderView, SIGNAL(refreshMailview(QList<RecMail>*)),this,SLOT(refreshMailView(QList<RecMail>*)));
QTimer::singleShot( 1000, this, SLOT( slotAdjustColumns() ) );
-
}
void MainWindow::slotAdjustLayout() {
diff --git a/noncore/net/mail/newmaildir.cpp b/noncore/net/mail/newmaildir.cpp
new file mode 100644
index 0000000..3fc66f4
--- a/dev/null
+++ b/noncore/net/mail/newmaildir.cpp
@@ -0,0 +1,34 @@
+#include "newmaildir.h"
+#include <qdialog.h>
+#include <qvariant.h>
+#include <qlineedit.h>
+#include <qcheckbox.h>
+
+Newmdirdlg::Newmdirdlg( QWidget* parent, const char* name)
+ : Newmdirdlgui(parent,name,true),ndir(""),possible_subs(false)
+{
+}
+
+Newmdirdlg::~Newmdirdlg()
+{
+}
+
+void Newmdirdlg::accept()
+{
+ ndir = dirnameEdit->text();
+ possible_subs = subdirsPossibleBox->isChecked();
+ if (ndir.isEmpty()) {
+ return;
+ }
+ Newmdirdlgui::accept();
+}
+
+const QString&Newmdirdlg::Newdir()const
+{
+ return ndir;
+}
+
+const bool Newmdirdlg::subpossible()const
+{
+ return possible_subs;
+}
diff --git a/noncore/net/mail/newmaildir.h b/noncore/net/mail/newmaildir.h
new file mode 100644
index 0000000..1eb904e
--- a/dev/null
+++ b/noncore/net/mail/newmaildir.h
@@ -0,0 +1,20 @@
+#include "newmaildirui.h"
+#include <qvariant.h>
+
+class Newmdirdlg : public Newmdirdlgui
+{
+ Q_OBJECT
+public:
+ Newmdirdlg( QWidget* parent = 0, const char* name = 0);
+ ~Newmdirdlg();
+
+ const QString&Newdir()const;
+ const bool subpossible()const;
+
+protected slots:
+ virtual void accept();
+
+protected:
+ QString ndir;
+ bool possible_subs;
+};
diff --git a/noncore/net/mail/newmaildirui.ui b/noncore/net/mail/newmaildirui.ui
new file mode 100644
index 0000000..72b2d04
--- a/dev/null
+++ b/noncore/net/mail/newmaildirui.ui
@@ -0,0 +1,100 @@
+<!DOCTYPE UI><UI>
+<class>Newmdirdlgui</class>
+<widget>
+ <class>QDialog</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>newmdirdlg</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>223</width>
+ <height>110</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>caption</name>
+ <string>Enter directory name</string>
+ </property>
+ <vbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>11</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Layout5</cstring>
+ </property>
+ <grid>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget row="0" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>dirnameLabel</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Directory name:</string>
+ </property>
+ </widget>
+ <widget row="0" column="1" >
+ <class>QLineEdit</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>dirnameEdit</cstring>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget>
+ <class>QCheckBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>subdirsPossibleBox</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Directory contains other subdirs</string>
+ </property>
+ </widget>
+ <spacer>
+ <property>
+ <name>name</name>
+ <cstring>Spacer4</cstring>
+ </property>
+ <property stdset="1">
+ <name>orientation</name>
+ <enum>Vertical</enum>
+ </property>
+ <property stdset="1">
+ <name>sizeType</name>
+ <enum>Expanding</enum>
+ </property>
+ <property>
+ <name>sizeHint</name>
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </vbox>
+</widget>
+</UI>