added channels file clean up warning

added channels private key notification, and new private channel key behaviour (must subscribe to accept a private key)

git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@3756 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
chrisparker126 2010-11-07 00:02:51 +00:00
parent 0f05f8d85e
commit 885d71370c
10 changed files with 696 additions and 517 deletions

View File

@ -42,7 +42,7 @@ const uint8_t RS_PKT_SUBTYPE_DISTRIB_CONFIG_DATA = 0x04;
/**************************************************************************/ /**************************************************************************/
/*! /*!
* This should be derived from to store RsDistrib child objects * This should be subclassed by p3distrib subclass's to store their data
* save data * save data
*/ */
class RsDistribChildConfig: public RsItem class RsDistribChildConfig: public RsItem

View File

@ -65,7 +65,6 @@ RsChannels *rsChannels = NULL;
/* remember 2^16 = 64K max units in store period. /* remember 2^16 = 64K max units in store period.
* PUBPERIOD * 2^16 = max STORE PERIOD */ * PUBPERIOD * 2^16 = max STORE PERIOD */
#define CHANNEL_STOREPERIOD (30*24*3600) /* 30 * 24 * 3600 - secs in a 30 day month */ #define CHANNEL_STOREPERIOD (30*24*3600) /* 30 * 24 * 3600 - secs in a 30 day month */
#define TEST_CHANNEL_STOREPERIOD (24*3600) /* one day */
#define CHANNEL_PUBPERIOD 600 /* 10 minutes ... (max = 455 days) */ #define CHANNEL_PUBPERIOD 600 /* 10 minutes ... (max = 455 days) */
#define MAX_AUTO_DL 1E9 /* auto download of attachment limit; 1 GIG */ #define MAX_AUTO_DL 1E9 /* auto download of attachment limit; 1 GIG */
@ -603,6 +602,14 @@ bool p3Channels::channelEditInfo(std::string chId, ChannelInfo& info){
} }
void p3Channels::getPubKeysAvailableGrpIds(std::list<std::string>& grpIds)
{
getGrpListPubKeyAvailable(grpIds);
return;
}
/***************************************************************************************/ /***************************************************************************************/
/****************** Event Feedback (Overloaded form p3distrib) *************************/ /****************** Event Feedback (Overloaded form p3distrib) *************************/
/***************************************************************************************/ /***************************************************************************************/
@ -795,7 +802,41 @@ void p3Channels::locked_notifyGroupChanged(GroupInfo &grp, uint32_t flags)
return p3GroupDistrib::locked_notifyGroupChanged(grp, flags); return p3GroupDistrib::locked_notifyGroupChanged(grp, flags);
} }
void p3Channels::cleanUpOldFiles(){ bool p3Channels::getCleanUpList(std::map<std::string, uint32_t>& warnings,const std::string& chId,uint32_t limit)
{
time_t now = time(NULL);
uint32_t timeLeft = 0;
bool first = true;
std::list<ChannelMsgSummary> msgList;
std::list<ChannelMsgSummary>::iterator msg_it;
ChannelMsgInfo chMsgInfo;
if(!getChannelMsgList(chId, msgList))
return false;
for(msg_it = msgList.begin(); msg_it != msgList.end(); msg_it++){
if(!getChannelMessage(chId, msg_it->msgId, chMsgInfo))
continue;
// if msg not close to warning limit leave it alone
if( chMsgInfo.ts > (now - CHANNEL_STOREPERIOD + limit))
continue;
timeLeft = CHANNEL_STOREPERIOD - (now - chMsgInfo.ts);
warnings.insert(std::pair<std::string, uint32_t>(msg_it->msgId, timeLeft));
}
}
void p3Channels::cleanUpOldFiles()
{
time_t now = time(NULL); time_t now = time(NULL);
std::list<ChannelInfo> chList; std::list<ChannelInfo> chList;

View File

@ -78,6 +78,8 @@ virtual bool channelExtraFileRemove(std::string hash, std::string chId);
virtual bool channelRestoreKeys(std::string chId); virtual bool channelRestoreKeys(std::string chId);
virtual bool channelShareKeys(std::string chId, std::list<std::string>& peers); virtual bool channelShareKeys(std::string chId, std::list<std::string>& peers);
virtual bool channelEditInfo(std::string chId, ChannelInfo &ci); virtual bool channelEditInfo(std::string chId, ChannelInfo &ci);
virtual void getPubKeysAvailableGrpIds(std::list<std::string>& grpIds);
virtual bool getCleanUpList(std::map<std::string, uint32_t>& warnings,const std::string& chId, uint32_t limit);
/***************************************************************************************/ /***************************************************************************************/
/****************** Event Feedback (Overloaded form p3distrib) *************************/ /****************** Event Feedback (Overloaded form p3distrib) *************************/
/***************************************************************************************/ /***************************************************************************************/

View File

@ -1230,6 +1230,9 @@ bool p3GroupDistrib::subscribeToGroup(std::string grpId, bool subscribe)
{ {
git->second.flags |= RS_DISTRIB_SUBSCRIBED; git->second.flags |= RS_DISTRIB_SUBSCRIBED;
if(attemptPublishKeysRecvd(git->second))
git->second.flags |= RS_DISTRIB_PUBLISH;
locked_notifyGroupChanged(git->second, GRP_SUBSCRIBED); locked_notifyGroupChanged(git->second, GRP_SUBSCRIBED);
mGroupsRepublish = true; mGroupsRepublish = true;
@ -1268,6 +1271,24 @@ bool p3GroupDistrib::subscribeToGroup(std::string grpId, bool subscribe)
return true; return true;
} }
bool p3GroupDistrib::attemptPublishKeysRecvd(GroupInfo& info)
{
std::map<std::string, RsDistribGrpKey*>::iterator mit;
mit = mRecvdPubKeys.find(info.grpId);
if(mit == mRecvdPubKeys.end())
return false;
if(locked_updateGroupPublishKey(info, mit->second))
mRecvdPubKeys.erase(mit);
else
return false;
return true;
}
/************************************* p3Config *************************************/ /************************************* p3Config *************************************/
RsSerialiser *p3GroupDistrib::setupSerialiser() RsSerialiser *p3GroupDistrib::setupSerialiser()
@ -2083,30 +2104,39 @@ void p3GroupDistrib::locked_receivePubKeys(){
void p3GroupDistrib::locked_loadRecvdPubKeys(){ void p3GroupDistrib::locked_loadRecvdPubKeys(){
std::map<std::string, RsDistribGrpKey* >::iterator mit; std::map<std::string, RsDistribGrpKey* >::iterator mit;
std::list<std::string>::iterator lit;
GroupInfo *gi; GroupInfo *gi;
std::list<std::string> toDelete; bool cont = false;
#ifdef DISTRIB_DEBUG #ifdef DISTRIB_DEBUG
std::cerr << "p3GroupDistrib::locked_loadRecvdPubKeys() " << std::endl; std::cerr << "p3GroupDistrib::locked_loadRecvdPubKeys() " << std::endl;
#endif #endif
bool ok = false;
// load received keys // look for keys to add to private publish key received notify list
for(mit = mRecvdPubKeys.begin(); mit != mRecvdPubKeys.end(); mit++ ){ for(mit = mRecvdPubKeys.begin(); mit != mRecvdPubKeys.end(); mit++ ){
gi = locked_getGroupInfo(mit->second->grpId); gi = locked_getGroupInfo(mit->second->grpId);
if(gi != NULL){ if(gi != NULL){
/* ensure grpId not added already */
for(lit=mPubKeyAvailableGrpId.begin(); lit != mPubKeyAvailableGrpId.end(); lit++){
if(mit->second->grpId == *lit){
if(locked_updateGroupPublishKey(*gi, mit->second)){ cont = true;
toDelete.push_back(mit->first); break;
ok |= true; }
} }
else
std::cerr << "p3GroupDistrib::locked_loadRecvdPubKeys(): Failed to load" << std::endl; if(cont)
{
cont = false;
continue;
}
mPubKeyAvailableGrpId.push_back(mit->second->grpId);
locked_notifyGroupChanged(*gi, GRP_UPDATE);
}else{ }else{
@ -2116,17 +2146,7 @@ void p3GroupDistrib::locked_loadRecvdPubKeys(){
} }
mLastRecvdKeyTime = time(NULL); mLastRecvdKeyTime = time(NULL);
if(ok)
IndicateConfigChanged();
std::list<std::string >::iterator lit;
// delete keys that have been loaded to groups
for(lit = toDelete.begin(); lit != toDelete.end(); lit++)
mRecvdPubKeys.erase(*lit);
return; return;
} }
@ -3146,6 +3166,13 @@ RsDistribMsg *p3GroupDistrib::unpackDistribSignedMsg(RsDistribSignedMsg *newMsg)
return distribMsg; return distribMsg;
} }
void p3GroupDistrib::getGrpListPubKeyAvailable(std::list<std::string>& grpList)
{
RsStackMutex stack(distribMtx);
grpList = mPubKeyAvailableGrpId;
return;
}
bool p3GroupDistrib::locked_checkDistribMsg( bool p3GroupDistrib::locked_checkDistribMsg(
GroupInfo &gi, RsDistribMsg *msg) GroupInfo &gi, RsDistribMsg *msg)

View File

@ -277,6 +277,12 @@ class p3GroupDistrib: public CacheSource, public CacheStore, public p3Config, pu
bool backUpKeys(const std::list<RsDistribGrpKey* > &keysToBackUp, std::string grpId); bool backUpKeys(const std::list<RsDistribGrpKey* > &keysToBackUp, std::string grpId);
void locked_sharePubKey(); void locked_sharePubKey();
/*!
* Attempt to load public key from recvd list if it exists for grpId
* @param grpId the id for the group for which private publish key is wanted
*/
bool attemptPublishKeysRecvd(GroupInfo& info);
protected: protected:
/* load cache msgs */ /* load cache msgs */
@ -341,6 +347,7 @@ class p3GroupDistrib: public CacheSource, public CacheStore, public p3Config, pu
bool subscribeToGroup(std::string grpId, bool subscribe); bool subscribeToGroup(std::string grpId, bool subscribe);
/***************************************************************************************/ /***************************************************************************************/
/***************************************************************************************/ /***************************************************************************************/
@ -377,6 +384,11 @@ class p3GroupDistrib: public CacheSource, public CacheStore, public p3Config, pu
GroupInfo *locked_getGroupInfo(std::string grpId); GroupInfo *locked_getGroupInfo(std::string grpId);
RsDistribMsg *locked_getGroupMsg(std::string grpId, std::string msgId); RsDistribMsg *locked_getGroupMsg(std::string grpId, std::string msgId);
/*!
* for retrieving the grpList for which public keys are available
*/
void getGrpListPubKeyAvailable(std::list<std::string>& grpList);
/* Filter Messages */ /* Filter Messages */
/***************************************************************************************/ /***************************************************************************************/
@ -497,9 +509,9 @@ class p3GroupDistrib: public CacheSource, public CacheStore, public p3Config, pu
*/ */
virtual void locked_receivePubKeys(); virtual void locked_receivePubKeys();
/** /*!
* This loads received pub keys * utility function to check whether grps exist
* * for private publish keys received
*/ */
virtual void locked_loadRecvdPubKeys(); virtual void locked_loadRecvdPubKeys();
@ -510,7 +522,7 @@ class p3GroupDistrib: public CacheSource, public CacheStore, public p3Config, pu
*/ */
virtual bool locked_editGroup(std::string grpId, GroupInfo& gi); virtual bool locked_editGroup(std::string grpId, GroupInfo& gi);
/** /*!
* Encrypts data using envelope encryption (taken from open ssl's evp_sealinit ) * Encrypts data using envelope encryption (taken from open ssl's evp_sealinit )
* only full publish key holders can encrypt data for given group * only full publish key holders can encrypt data for given group
*@param out *@param out
@ -671,6 +683,7 @@ class p3GroupDistrib: public CacheSource, public CacheStore, public p3Config, pu
std::map<std::string, RsDistribGrpKey* > mRecvdPubKeys; /// full publishing keys received from users std::map<std::string, RsDistribGrpKey* > mRecvdPubKeys; /// full publishing keys received from users
std::map<std::string, std::list<std::string> > mPendingPubKeyRecipients; /// peers to receive publics key for a given grp std::map<std::string, std::list<std::string> > mPendingPubKeyRecipients; /// peers to receive publics key for a given grp
std::list<std::string> mPubKeyAvailableGrpId; // groups id for which public keys are available
time_t mLastKeyPublishTime, mLastRecvdKeyTime; time_t mLastKeyPublishTime, mLastRecvdKeyTime;
}; };

View File

@ -26,6 +26,8 @@
#include <iostream> #include <iostream>
#include <algorithm> #include <algorithm>
#include <set>
#include <map>
#include "ChannelFeed.h" #include "ChannelFeed.h"
@ -56,6 +58,8 @@
#define COMBO_TITLE_INDEX 0 #define COMBO_TITLE_INDEX 0
#define COMBO_DESC_INDEX 1 #define COMBO_DESC_INDEX 1
#define WARNING_LIMIT 3600*24*2
/**** /****
* #define CHAN_DEBUG * #define CHAN_DEBUG
***/ ***/
@ -181,7 +185,7 @@ void ChannelFeed::channelListCustomPopupMenu( QPoint point )
contextMnu.addAction( shareKeyAct ); contextMnu.addAction( shareKeyAct );
contextMnu.addAction( channeldetailsAct ); contextMnu.addAction( channeldetailsAct );
} }
else if (ci.channelFlags & RS_DISTRIB_PUBLISH) { else if ((ci.channelFlags & RS_DISTRIB_PUBLISH) && (ci.channelFlags & RS_DISTRIB_SUBSCRIBED)) {
contextMnu.addAction( postchannelAct ); contextMnu.addAction( postchannelAct );
contextMnu.addSeparator(); contextMnu.addSeparator();
contextMnu.addAction( channeldetailsAct ); contextMnu.addAction( channeldetailsAct );
@ -350,10 +354,9 @@ void ChannelFeed::updateChannelList()
/* sort it into Publish (Own), Subscribed, Popular and Other */ /* sort it into Publish (Own), Subscribed, Popular and Other */
uint32_t flags = it->channelFlags; uint32_t flags = it->channelFlags;
if ((flags & (RS_DISTRIB_ADMIN | RS_DISTRIB_PUBLISH)) && (flags & RS_DISTRIB_SUBSCRIBED) if ((flags & RS_DISTRIB_ADMIN) && (flags & RS_DISTRIB_PUBLISH) && (flags & RS_DISTRIB_SUBSCRIBED)) {
) {
adminList.push_back(*it); adminList.push_back(*it);
} else if (flags & RS_DISTRIB_SUBSCRIBED) { } else if ((flags & RS_DISTRIB_SUBSCRIBED) || ((flags & RS_DISTRIB_SUBSCRIBED) && (flags &RS_DISTRIB_PUBLISH)) ) {
subList.push_back(*it); subList.push_back(*it);
} else { } else {
/* rate the others by popularity */ /* rate the others by popularity */
@ -394,6 +397,11 @@ void ChannelFeed::updateChannelList()
fillChannelList(POPULAR, popList); fillChannelList(POPULAR, popList);
fillChannelList(OTHER, otherList); fillChannelList(OTHER, otherList);
// place notices for channel with private keys available
highlightPrivateKeys(SUBSCRIBED);
highlightPrivateKeys(POPULAR);
highlightPrivateKeys(OTHER);
updateMessageSummaryList(""); updateMessageSummaryList("");
} }
@ -428,8 +436,44 @@ void ChannelFeed::filterChannelList(std::list<ChannelInfo> &ci){
} }
void ChannelFeed::fillChannelList(int channelItem, std::list<ChannelInfo> &channelInfos) void ChannelFeed::highlightPrivateKeys(int group){
{
QStandardItem *groupItem = model->item(group);
QStandardItem *item = NULL;
std::list<std::string> keysAvailable;
std::list<std::string>::iterator it;
int rowCount = 0;
QBrush brush;
brush.setColor(Qt::blue);
if((groupItem == NULL) || (rsChannels == NULL))
return;
rowCount = groupItem->rowCount();
rsChannels->getPubKeysAvailableGrpIds(keysAvailable);
for(it= keysAvailable.begin(); it != keysAvailable.end(); it++)
for (int row = 0; row < rowCount; row++) {
if (groupItem->child(row, COLUMN_DATA)->data(ROLE_ID).toString() == QString::fromStdString(*it)) {
/* found channel */
item = groupItem->child(row, COLUMN_NAME);
/* set title text to bold and colored blue */
QFont chanFont = item->font();
chanFont.setBold(true);
item->setFont(chanFont);
item->setForeground(brush);
item->setToolTip(item->toolTip() + QString("\nPrivate Key Available"));
}
}
}
void ChannelFeed::fillChannelList(int channelItem, std::list<ChannelInfo> &channelInfos){
std::list<ChannelInfo>::iterator iit; std::list<ChannelInfo>::iterator iit;
/* remove rows with groups before adding new ones */ /* remove rows with groups before adding new ones */
@ -485,7 +529,7 @@ void ChannelFeed::fillChannelList(int channelItem, std::list<ChannelInfo> &chann
groupItem->child(chNameItem->index().row(), COLUMN_DATA)->setData(QDateTime::fromTime_t(ci.lastPost), ROLE_CHANNEL_TS); groupItem->child(chNameItem->index().row(), COLUMN_DATA)->setData(QDateTime::fromTime_t(ci.lastPost), ROLE_CHANNEL_TS);
chNameItem->setToolTip(tr("Popularity: %1\nFetches: %2\nAvailable: %3").arg(QString::number(ci.pop)).arg(9999).arg(9999)); chNameItem->setToolTip(tr("Popularity: %1").arg(QString::number(ci.pop)));
QPixmap chanImage; QPixmap chanImage;
if (ci.pngImageLen != 0) { if (ci.pngImageLen != 0) {
@ -545,6 +589,8 @@ void ChannelFeed::updateMessageSummaryList(const std::string &channelId)
{ {
int channelItems[2] = { OWN, SUBSCRIBED }; int channelItems[2] = { OWN, SUBSCRIBED };
for (int channelItem = 0; channelItem < 2; channelItem++) { for (int channelItem = 0; channelItem < 2; channelItem++) {
QStandardItem *groupItem = model->item(channelItems[channelItem]); QStandardItem *groupItem = model->item(channelItems[channelItem]);
if (groupItem == NULL) { if (groupItem == NULL) {
@ -658,14 +704,23 @@ void ChannelFeed::updateChannelMsgs()
std::list<ChannelMsgSummary> msgs; std::list<ChannelMsgSummary> msgs;
std::list<ChannelMsgSummary>::iterator it; std::list<ChannelMsgSummary>::iterator it;
rsChannels->getChannelMsgList(mChannelId, msgs); rsChannels->getChannelMsgList(mChannelId, msgs);
msgs.sort(sortChannelMsgSummary); msgs.sort(sortChannelMsgSummary);
/* set get warning list for channel */
std::map<std::string, uint32_t> warningList;
std::map<std::string, uint32_t>::iterator msgId_it;
rsChannels->getCleanUpList(warningList, mChannelId, WARNING_LIMIT);
for(it = msgs.begin(); it != msgs.end(); it++) { for(it = msgs.begin(); it != msgs.end(); it++) {
ChanMsgItem *cmi = new ChanMsgItem(this, 0, mChannelId, it->msgId, true); ChanMsgItem *cmi = new ChanMsgItem(this, 0, mChannelId, it->msgId, true);
msgId_it = warningList.find(it->msgId);
if(msgId_it != warningList.end())
cmi->setFileCleanUpWarning(msgId_it->second);
mChanMsgItems.push_back(cmi); mChanMsgItems.push_back(cmi);
verticalLayout_2->addWidget(cmi); verticalLayout_2->addWidget(cmi);
} }

View File

@ -86,7 +86,7 @@ private slots:
void finishSearching(); void finishSearching();
private: private:
void highlightPrivateKeys(int group);
void updateChannelList(); void updateChannelList();
void fillChannelList(int channelItem, std::list<ChannelInfo> &channelInfos); void fillChannelList(int channelItem, std::list<ChannelInfo> &channelInfos);
void filterChannelList(std::list<ChannelInfo>&); void filterChannelList(std::list<ChannelInfo>&);

View File

@ -64,10 +64,13 @@ ChanMsgItem::ChanMsgItem(FeedHolder *parent, uint32_t feedId, std::string chanId
downloadButton->hide(); downloadButton->hide();
playButton->hide(); playButton->hide();
warn_image_label->hide();
warning_label->hide();
titleLabel->setMinimumWidth(100); titleLabel->setMinimumWidth(100);
subjectLabel->setMinimumWidth(100); subjectLabel->setMinimumWidth(100);
small(); small();
updateItemStatic(); updateItemStatic();
updateItem(); updateItem();
@ -90,6 +93,8 @@ void ChanMsgItem::updateItemStatic()
if (!rsChannels->getChannelMessage(mChanId, mMsgId, cmi)) if (!rsChannels->getChannelMessage(mChanId, mMsgId, cmi))
return; return;
m_inUpdateItemStatic = true; m_inUpdateItemStatic = true;
QString title; QString title;
@ -201,6 +206,25 @@ void ChanMsgItem::updateItemStatic()
} }
void ChanMsgItem::setFileCleanUpWarning(uint32_t time_left)
{
int hours = (int)time_left/3600;
int minutes = (time_left - hours*3600)%60;
warning_label->setText(tr("Warning! You have less than %1 hours and %2 minute before this file is delted Consider saving it.").arg(
QString::number(hours)).arg(QString::number(minutes)));
QFont warnFont = warning_label->font();
warnFont.setBold(true);
warning_label->setFont(warnFont);
warn_image_label->setVisible(true);
warning_label->setVisible(true);
return;
}
void ChanMsgItem::updateItem() void ChanMsgItem::updateItem()
{ {
/* fill in */ /* fill in */

View File

@ -40,6 +40,7 @@ public:
void updateItemStatic(); void updateItemStatic();
void small(); void small();
void setFileCleanUpWarning(uint32_t time_left);
private slots: private slots:
/* default stuff */ /* default stuff */

View File

@ -1,481 +1,497 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0"> <ui version="4.0">
<class>ChanMsgItem</class> <class>ChanMsgItem</class>
<widget class="QWidget" name="ChanMsgItem"> <widget class="QWidget" name="ChanMsgItem">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>518</width> <width>528</width>
<height>208</height> <height>208</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
<string notr="true"/> <string notr="true"/>
</property> </property>
<property name="styleSheet"> <property name="styleSheet">
<string notr="true">QToolButton, QPushButton, QComboBox { <string notr="true">QToolButton, QPushButton, QComboBox {
border-image: url(:/images/btn_26.png) 4; border-image: url(:/images/btn_26.png) 4;
border-width: 4; border-width: 4;
padding: 0px 6px; padding: 0px 6px;
font-size: 12px; font-size: 12px;
} }
QToolButton:hover, QPushButton:hover, QComboBox:hover { QToolButton:hover, QPushButton:hover, QComboBox:hover {
border-image: url(:/images/btn_26_hover.png) 4; border-image: url(:/images/btn_26_hover.png) 4;
} }
QToolButton:disabled, QPushButton:disabled, QComboBox::disabled { QToolButton:disabled, QPushButton:disabled, QComboBox::disabled {
color:gray; color:gray;
} }
QToolButton:pressed, QPushButton:pressed{ QToolButton:pressed, QPushButton:pressed{
border-image: url(:/images/btn_26_pressed.png) 4; border-image: url(:/images/btn_26_pressed.png) 4;
}</string> }</string>
</property> </property>
<layout class="QGridLayout" name="gridLayout_4"> <layout class="QGridLayout" name="gridLayout_4">
<property name="leftMargin"> <property name="leftMargin">
<number>6</number> <number>6</number>
</property> </property>
<property name="topMargin"> <property name="topMargin">
<number>1</number> <number>1</number>
</property> </property>
<property name="rightMargin"> <property name="rightMargin">
<number>6</number> <number>6</number>
</property> </property>
<property name="bottomMargin"> <property name="bottomMargin">
<number>1</number> <number>1</number>
</property> </property>
<property name="horizontalSpacing"> <property name="horizontalSpacing">
<number>6</number> <number>6</number>
</property> </property>
<property name="verticalSpacing"> <property name="verticalSpacing">
<number>1</number> <number>1</number>
</property> </property>
<item row="0" column="0"> <item row="0" column="0">
<widget class="QFrame" name="frame"> <widget class="QFrame" name="frame">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed"> <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch> <horstretch>0</horstretch>
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<property name="maximumSize"> <property name="maximumSize">
<size> <size>
<width>16777215</width> <width>16777215</width>
<height>140</height> <height>140</height>
</size> </size>
</property> </property>
<property name="styleSheet"> <property name="styleSheet">
<string notr="true">QFrame#frame{border: 3px solid #D3D3D3; <string notr="true">QFrame#frame{border: 3px solid #D3D3D3;
background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1,
stop:0 #FFFFFF, stop:1 #F2F2F2);; stop:0 #FFFFFF, stop:1 #F2F2F2);;
border-radius: 10px;}</string> border-radius: 10px;}</string>
</property> </property>
<property name="frameShape"> <property name="frameShape">
<enum>QFrame::StyledPanel</enum> <enum>QFrame::StyledPanel</enum>
</property> </property>
<property name="frameShadow"> <property name="frameShadow">
<enum>QFrame::Raised</enum> <enum>QFrame::Raised</enum>
</property> </property>
<layout class="QGridLayout" name="gridLayout_3"> <layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0"> <item row="0" column="0">
<layout class="QGridLayout" name="gridLayout_2"> <layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0"> <item row="0" column="0">
<widget class="QLabel" name="label"> <widget class="QLabel" name="label">
<property name="maximumSize"> <property name="maximumSize">
<size> <size>
<width>156</width> <width>156</width>
<height>107</height> <height>107</height>
</size> </size>
</property> </property>
<property name="text"> <property name="text">
<string/> <string/>
</property> </property>
<property name="pixmap"> <property name="pixmap">
<pixmap resource="../images.qrc">:/images/thumb-default-video.png</pixmap> <pixmap resource="../images.qrc">:/images/thumb-default-video.png</pixmap>
</property> </property>
<property name="scaledContents"> <property name="scaledContents">
<bool>true</bool> <bool>true</bool>
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="0"> <item row="1" column="0">
<spacer name="verticalSpacer"> <spacer name="verticalSpacer">
<property name="orientation"> <property name="orientation">
<enum>Qt::Vertical</enum> <enum>Qt::Vertical</enum>
</property> </property>
<property name="sizeType"> <property name="sizeType">
<enum>QSizePolicy::Expanding</enum> <enum>QSizePolicy::Expanding</enum>
</property> </property>
<property name="sizeHint" stdset="0"> <property name="sizeHint" stdset="0">
<size> <size>
<width>138</width> <width>138</width>
<height>1</height> <height>1</height>
</size> </size>
</property> </property>
</spacer> </spacer>
</item> </item>
</layout> </layout>
</item> </item>
<item row="0" column="1"> <item row="0" column="1">
<layout class="QGridLayout" name="gridLayout"> <layout class="QGridLayout" name="gridLayout">
<property name="horizontalSpacing"> <property name="horizontalSpacing">
<number>4</number> <number>4</number>
</property> </property>
<item row="0" column="0" rowspan="2" colspan="5"> <item row="0" column="0" rowspan="2" colspan="5">
<widget class="QLabel" name="titleLabel"> <widget class="QLabel" name="titleLabel">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum"> <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch> <horstretch>0</horstretch>
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<property name="font"> <property name="font">
<font> <font>
<pointsize>11</pointsize> <pointsize>11</pointsize>
<weight>75</weight> <weight>75</weight>
<italic>true</italic> <italic>true</italic>
<bold>true</bold> <bold>true</bold>
<stylestrategy>PreferAntialias</stylestrategy> <stylestrategy>PreferAntialias</stylestrategy>
</font> </font>
</property> </property>
<property name="text"> <property name="text">
<string notr="true">&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt; <string notr="true">&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt; &lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; } p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'MS Shell Dlg 2'; font-size:11pt; font-weight:600; font-style:italic;&quot;&gt; &lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'MS Shell Dlg 2'; font-size:11pt; font-weight:600; font-style:italic;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-style:normal; color:#656565;&quot;&gt;Channel Subject&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> &lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-style:normal; color:#656565;&quot;&gt;Channel Subject&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="scaledContents"> <property name="scaledContents">
<bool>false</bool> <bool>false</bool>
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="5" rowspan="2" colspan="4"> <item row="0" column="5" rowspan="2" colspan="4">
<widget class="QLabel" name="datetimelabel"> <widget class="QLabel" name="datetimelabel">
<property name="font"> <property name="font">
<font> <font>
<weight>75</weight> <weight>75</weight>
<bold>true</bold> <bold>true</bold>
<stylestrategy>PreferAntialias</stylestrategy> <stylestrategy>PreferAntialias</stylestrategy>
</font> </font>
</property> </property>
<property name="text"> <property name="text">
<string notr="true">&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt; <string notr="true">&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt; &lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; } p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:600; font-style:normal;&quot;&gt; &lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:600; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:8pt; color:#666666;&quot;&gt;DateTime&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> &lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:8pt; color:#666666;&quot;&gt;DateTime&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="6" colspan="3"> <item row="2" column="6" colspan="3">
<widget class="QLabel" name="filelabel"> <widget class="QLabel" name="filelabel">
<property name="font"> <property name="font">
<font> <font>
<stylestrategy>PreferAntialias</stylestrategy> <stylestrategy>PreferAntialias</stylestrategy>
</font> </font>
</property> </property>
<property name="text"> <property name="text">
<string notr="true">fileLabel</string> <string notr="true">fileLabel</string>
</property> </property>
<property name="alignment"> <property name="alignment">
<set>Qt::AlignRight|Qt::AlignTop|Qt::AlignTrailing</set> <set>Qt::AlignRight|Qt::AlignTop|Qt::AlignTrailing</set>
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="0" colspan="6"> <item row="2" column="0" colspan="6">
<widget class="QLabel" name="subjectLabel"> <widget class="QLabel" name="subjectLabel">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Expanding"> <sizepolicy hsizetype="MinimumExpanding" vsizetype="Expanding">
<horstretch>0</horstretch> <horstretch>0</horstretch>
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<property name="maximumSize"> <property name="maximumSize">
<size> <size>
<width>16777215</width> <width>16777215</width>
<height>60</height> <height>60</height>
</size> </size>
</property> </property>
<property name="text"> <property name="text">
<string notr="true">&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt; <string notr="true">&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt; &lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; } p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;&quot;&gt; &lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:8pt; color:#666666;&quot;&gt;Short Description&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> &lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:8pt; color:#666666;&quot;&gt;Short Description&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="wordWrap"> <property name="wordWrap">
<bool>true</bool> <bool>true</bool>
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="0"> <item row="4" column="0">
<widget class="QPushButton" name="readButton"> <widget class="QPushButton" name="readButton">
<property name="maximumSize"> <property name="maximumSize">
<size> <size>
<width>24</width> <width>24</width>
<height>16777215</height> <height>16777215</height>
</size> </size>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt; <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt; &lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; } p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans'; font-weight:400; font-style:normal;&quot;&gt; &lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans'; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Toggle Message Read Status&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> &lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Toggle Message Read Status&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="icon"> <property name="icon">
<iconset resource="../images.qrc"> <iconset resource="../images.qrc">
<normaloff>:/images/message-state-unread.png</normaloff>:/images/message-state-unread.png</iconset> <normaloff>:/images/message-state-unread.png</normaloff>:/images/message-state-unread.png</iconset>
</property> </property>
<property name="checkable"> <property name="checkable">
<bool>true</bool> <bool>true</bool>
</property> </property>
<property name="checked"> <property name="checked">
<bool>false</bool> <bool>false</bool>
</property> </property>
<property name="flat"> <property name="flat">
<bool>false</bool> <bool>false</bool>
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="1"> <item row="4" column="1">
<widget class="QLabel" name="newLabel"> <widget class="QLabel" name="newLabel">
<property name="maximumSize"> <property name="maximumSize">
<size> <size>
<width>16777215</width> <width>16777215</width>
<height>21</height> <height>21</height>
</size> </size>
</property> </property>
<property name="font"> <property name="font">
<font> <font>
<stylestrategy>PreferAntialias</stylestrategy> <stylestrategy>PreferAntialias</stylestrategy>
</font> </font>
</property> </property>
<property name="styleSheet"> <property name="styleSheet">
<string notr="true">QLabel{border: 1px solid #167BE7; <string notr="true">QLabel{border: 1px solid #167BE7;
background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
stop: 0 #2291E0, stop: 1 #3EB3FF); stop: 0 #2291E0, stop: 1 #3EB3FF);
border-radius: 3px}</string> border-radius: 3px}</string>
</property> </property>
<property name="text"> <property name="text">
<string>New</string> <string>New</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="2"> <item row="4" column="2">
<widget class="QPushButton" name="downloadButton"> <widget class="QPushButton" name="downloadButton">
<property name="font"> <property name="font">
<font> <font>
<pointsize>-1</pointsize> <pointsize>-1</pointsize>
</font> </font>
</property> </property>
<property name="text"> <property name="text">
<string>Download</string> <string>Download</string>
</property> </property>
<property name="icon"> <property name="icon">
<iconset resource="../images.qrc"> <iconset resource="../images.qrc">
<normaloff>:/images/download16.png</normaloff>:/images/download16.png</iconset> <normaloff>:/images/download16.png</normaloff>:/images/download16.png</iconset>
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="3"> <item row="4" column="3">
<widget class="QPushButton" name="playButton"> <widget class="QPushButton" name="playButton">
<property name="font"> <property name="font">
<font> <font>
<pointsize>-1</pointsize> <pointsize>-1</pointsize>
</font> </font>
</property> </property>
<property name="text"> <property name="text">
<string>Play</string> <string>Play</string>
</property> </property>
<property name="icon"> <property name="icon">
<iconset resource="../images.qrc"> <iconset resource="../images.qrc">
<normaloff>:/images/player_play.png</normaloff>:/images/player_play.png</iconset> <normaloff>:/images/player_play.png</normaloff>:/images/player_play.png</iconset>
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="4"> <item row="4" column="4">
<spacer> <spacer>
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
<property name="sizeType"> <property name="sizeType">
<enum>QSizePolicy::Expanding</enum> <enum>QSizePolicy::Expanding</enum>
</property> </property>
<property name="sizeHint" stdset="0"> <property name="sizeHint" stdset="0">
<size> <size>
<width>13</width> <width>13</width>
<height>21</height> <height>21</height>
</size> </size>
</property> </property>
</spacer> </spacer>
</item> </item>
<item row="3" column="5" colspan="2"> <item row="4" column="5" colspan="2">
<widget class="QPushButton" name="unsubscribeButton"> <widget class="QPushButton" name="unsubscribeButton">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed"> <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch> <horstretch>0</horstretch>
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<property name="maximumSize"> <property name="maximumSize">
<size> <size>
<width>24</width> <width>24</width>
<height>16777215</height> <height>16777215</height>
</size> </size>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>Unsubscribe From Channel</string> <string>Unsubscribe From Channel</string>
</property> </property>
<property name="text"> <property name="text">
<string/> <string/>
</property> </property>
<property name="icon"> <property name="icon">
<iconset resource="../images.qrc"> <iconset resource="../images.qrc">
<normaloff>:/images/mail_delete.png</normaloff>:/images/mail_delete.png</iconset> <normaloff>:/images/mail_delete.png</normaloff>:/images/mail_delete.png</iconset>
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="7"> <item row="4" column="7">
<widget class="QPushButton" name="clearButton"> <widget class="QPushButton" name="clearButton">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed"> <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch> <horstretch>0</horstretch>
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<property name="maximumSize"> <property name="maximumSize">
<size> <size>
<width>24</width> <width>24</width>
<height>16777215</height> <height>16777215</height>
</size> </size>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>Remove Item</string> <string>Remove Item</string>
</property> </property>
<property name="text"> <property name="text">
<string/> <string/>
</property> </property>
<property name="icon"> <property name="icon">
<iconset resource="../images.qrc"> <iconset resource="../images.qrc">
<normaloff>:/images/close_normal.png</normaloff>:/images/close_normal.png</iconset> <normaloff>:/images/close_normal.png</normaloff>:/images/close_normal.png</iconset>
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="8"> <item row="4" column="8">
<widget class="QPushButton" name="expandButton"> <widget class="QPushButton" name="expandButton">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed"> <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch> <horstretch>0</horstretch>
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<property name="maximumSize"> <property name="maximumSize">
<size> <size>
<width>24</width> <width>24</width>
<height>16777215</height> <height>16777215</height>
</size> </size>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>Expand</string> <string>Expand</string>
</property> </property>
<property name="styleSheet"> <property name="styleSheet">
<string notr="true"/> <string notr="true"/>
</property> </property>
<property name="text"> <property name="text">
<string/> <string/>
</property> </property>
<property name="icon"> <property name="icon">
<iconset resource="../images.qrc"> <iconset resource="../images.qrc">
<normaloff>:/images/edit_add24.png</normaloff>:/images/edit_add24.png</iconset> <normaloff>:/images/edit_add24.png</normaloff>:/images/edit_add24.png</iconset>
</property> </property>
</widget> </widget>
</item> </item>
</layout> <item row="3" column="0">
</item> <widget class="QLabel" name="warn_image_label">
</layout> <property name="text">
</widget> <string/>
</item> </property>
<item row="1" column="0"> <property name="pixmap">
<widget class="QFrame" name="expandFrame"> <pixmap resource="../images.qrc">:/images/status_unknown.png</pixmap>
<property name="styleSheet"> </property>
<string notr="true">QFrame#expandFrame{border: 2px solid #D3D3D3; </widget>
background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, </item>
stop:0 #FFFFFF, stop:1 #F2F2F2);; <item row="3" column="1">
border-radius: 10px;}</string> <widget class="QLabel" name="warning_label">
</property> <property name="text">
<property name="frameShape"> <string>TextLabel</string>
<enum>QFrame::StyledPanel</enum> </property>
</property> </widget>
<property name="frameShadow"> </item>
<enum>QFrame::Raised</enum> </layout>
</property> </item>
<layout class="QVBoxLayout"> </layout>
<item> </widget>
<widget class="QLabel" name="msgLabel"> </item>
<property name="sizePolicy"> <item row="1" column="0">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred"> <widget class="QFrame" name="expandFrame">
<horstretch>0</horstretch> <property name="styleSheet">
<verstretch>0</verstretch> <string notr="true">QFrame#expandFrame{border: 2px solid #D3D3D3;
</sizepolicy> background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1,
</property> stop:0 #FFFFFF, stop:1 #F2F2F2);;
<property name="font"> border-radius: 10px;}</string>
<font> </property>
<stylestrategy>PreferAntialias</stylestrategy> <property name="frameShape">
</font> <enum>QFrame::StyledPanel</enum>
</property> </property>
<property name="styleSheet"> <property name="frameShadow">
<string notr="true">QLabel#msgLabel{border: 2px solid #238; <enum>QFrame::Raised</enum>
border-radius: 10px;}</string> </property>
</property> <layout class="QVBoxLayout">
<property name="text"> <item>
<string notr="true">Long <widget class="QLabel" name="msgLabel">
message here</string> <property name="sizePolicy">
</property> <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
<property name="wordWrap"> <horstretch>0</horstretch>
<bool>true</bool> <verstretch>0</verstretch>
</property> </sizepolicy>
</widget> </property>
</item> <property name="font">
</layout> <font>
</widget> <stylestrategy>PreferAntialias</stylestrategy>
</item> </font>
<item row="2" column="0"> </property>
<spacer name="verticalSpacer_2"> <property name="styleSheet">
<property name="orientation"> <string notr="true">QLabel#msgLabel{border: 2px solid #238;
<enum>Qt::Vertical</enum> border-radius: 10px;}</string>
</property> </property>
<property name="sizeHint" stdset="0"> <property name="text">
<size> <string notr="true"/>
<width>20</width> </property>
<height>5</height> <property name="wordWrap">
</size> <bool>true</bool>
</property> </property>
</spacer> </widget>
</item> </item>
</layout> </layout>
</widget> </widget>
<resources> </item>
<include location="../images.qrc"/> <item row="2" column="0">
<include location="../images.qrc"/> <spacer name="verticalSpacer_2">
<include location="../images.qrc"/> <property name="orientation">
<include location="../images.qrc"/> <enum>Qt::Vertical</enum>
<include location="../images.qrc"/> </property>
<include location="../images.qrc"/> <property name="sizeHint" stdset="0">
<include location="../images.qrc"/> <size>
<include location="../images.qrc"/> <width>20</width>
<include location="../images.qrc"/> <height>5</height>
<include location="../images.qrc"/> </size>
<include location="../images.qrc"/> </property>
<include location="../images.qrc"/> </spacer>
<include location="../images.qrc"/> </item>
<include location="../images.qrc"/> </layout>
<include location="../images.qrc"/> </widget>
<include location="../images.qrc"/> <resources>
<include location="../images.qrc"/> <include location="../images.qrc"/>
</resources> <include location="../images.qrc"/>
<connections/> <include location="../images.qrc"/>
</ui> <include location="../images.qrc"/>
<include location="../images.qrc"/>
<include location="../images.qrc"/>
<include location="../images.qrc"/>
<include location="../images.qrc"/>
<include location="../images.qrc"/>
<include location="../images.qrc"/>
<include location="../images.qrc"/>
<include location="../images.qrc"/>
<include location="../images.qrc"/>
<include location="../images.qrc"/>
<include location="../images.qrc"/>
<include location="../images.qrc"/>
<include location="../images.qrc"/>
</resources>
<connections/>
</ui>