diff --git a/retroshare-gui/src/gui/unfinished/blogs/BlogsDialog.cpp b/retroshare-gui/src/gui/unfinished/blogs/BlogsDialog.cpp new file mode 100644 index 000000000..01ecc3ad6 --- /dev/null +++ b/retroshare-gui/src/gui/unfinished/blogs/BlogsDialog.cpp @@ -0,0 +1,585 @@ +/**************************************************************** + * RetroShare is distributed under the following license: + * + * Copyright (C) 2008 Robert Fernie + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "rsiface/rsblogs.h" +#include "rsiface/rspeers.h" //to retrieve peer/usrId info + +#include "BlogsDialog.h" + +#include "BlogsMsgItem.h" +#include "CreateBlog.h" +#include "CreateBlogMsg.h" + +#include "gui/ChanGroupDelegate.h" +#include "gui/GeneralMsgDialog.h" + + +/** Constructor */ +BlogsDialog::BlogsDialog(QWidget *parent) +: MainPage (parent) +{ + /* Invoke the Qt Designer generated object setup routine */ + setupUi(this); + + connect(actionCreate_Channel, SIGNAL(triggered()), this, SLOT(createChannel())); + connect(postButton, SIGNAL(clicked()), this, SLOT(createMsg())); + connect(subscribeButton, SIGNAL( clicked( void ) ), this, SLOT( subscribeChannel ( void ) ) ); + connect(unsubscribeButton, SIGNAL( clicked( void ) ), this, SLOT( unsubscribeChannel ( void ) ) ); + + + mBlogId = ""; + mPeerId = rsPeers->getOwnId(); // add your id + + model = new QStandardItemModel(0, 2, this); + model->setHeaderData(0, Qt::Horizontal, tr("Name"), Qt::DisplayRole); + model->setHeaderData(1, Qt::Horizontal, tr("ID"), Qt::DisplayRole); + + treeView->setModel(model); + treeView->setEditTriggers(QAbstractItemView::NoEditTriggers); + + treeView->setItemDelegate(new ChanGroupDelegate()); + //treeView->setRootIsDecorated(false); + + // hide header and id column + treeView->setHeaderHidden(true); + treeView->hideColumn(1); + + QStandardItem *item1 = new QStandardItem(tr("Own Blogs")); + QStandardItem *item2 = new QStandardItem(tr("Subscribed Blogs")); + QStandardItem *item3 = new QStandardItem(tr("Popular Blogs")); + QStandardItem *item4 = new QStandardItem(tr("Other Blogs")); + + model->appendRow(item1); + model->appendRow(item2); + model->appendRow(item3); + model->appendRow(item4); + + connect(treeView, SIGNAL(clicked(const QModelIndex &)), this, SLOT(selectChannel(const QModelIndex &))); + connect(treeView, SIGNAL(activated(const QModelIndex &)), this, SLOT(toggleSelection(const QModelIndex &))); + connect(treeView, SIGNAL(customContextMenuRequested( QPoint ) ), this, SLOT( channelListCustomPopupMenu( QPoint ) ) ); + + //added from ahead + updateChannelList(); + + mChannelFont = QFont("MS SANS SERIF", 22); + nameLabel->setFont(mChannelFont); + + nameLabel->setMinimumWidth(20); + + itemFont = QFont("ARIAL", 10); + itemFont.setBold(true); + item1->setFont(itemFont); + item2->setFont(itemFont); + item3->setFont(itemFont); + item4->setFont(itemFont); + + item1->setForeground(QBrush(QColor(79, 79, 79))); + item2->setForeground(QBrush(QColor(79, 79, 79))); + item3->setForeground(QBrush(QColor(79, 79, 79))); + item4->setForeground(QBrush(QColor(79, 79, 79))); + + QMenu *channelmenu = new QMenu(); + channelmenu->addAction(actionCreate_Channel); + channelmenu->addSeparator(); + channelpushButton->setMenu(channelmenu); + + + QTimer *timer = new QTimer(this); + timer->connect(timer, SIGNAL(timeout()), this, SLOT(checkUpdate())); + timer->start(1000); +} + +void BlogsDialog::channelListCustomPopupMenu( QPoint point ) +{ + QMenu contextMnu( this ); + QMouseEvent *mevent = new QMouseEvent( QEvent::MouseButtonPress, point, Qt::RightButton, Qt::RightButton, Qt::NoModifier ); + + QAction *channeldetailsAct = new QAction(QIcon(":/images/info16.png"), tr( "Show Channel Details" ), this ); + connect( channeldetailsAct , SIGNAL( triggered() ), this, SLOT( showChannelDetails() ) ); + + contextMnu.clear(); + contextMnu.addAction( channeldetailsAct ); + + contextMnu.exec( mevent->globalPos() ); + + +} + +void BlogsDialog::createChannel() +{ + CreateBlog *cf = new CreateBlog(NULL, false); + + cf->setWindowTitle(tr("Create a new Blog")); + cf->show(); +} + +void BlogsDialog::channelSelection() +{ + /* which item was selected? */ + + + /* update mBlogId */ + + updateChannelMsgs(); +} + + +/*************************************************************************************/ +/*************************************************************************************/ +/*************************************************************************************/ + +void BlogsDialog::deleteFeedItem(QWidget *item, uint32_t type) +{ + return; +} + +void BlogsDialog::openChat(std::string peerId) +{ + return; +} + +void BlogsDialog::openMsg(uint32_t type, std::string grpId, std::string inReplyTo) +{ +#ifdef CHAN_DEBUG + std::cerr << "BlogsDialog::openMsg()"; + std::cerr << std::endl; +#endif + GeneralMsgDialog *msgDialog = new GeneralMsgDialog(NULL); + + + msgDialog->addDestination(type, grpId, inReplyTo); + + msgDialog->show(); + return; +} + + +void BlogsDialog::createMsg() +{ + if (mBlogId == "") + { + return; + } + + CreateBlogMsg *msgDialog = new CreateBlogMsg(mBlogId); + + msgDialog->show(); + return; +} + +void BlogsDialog::selectChannel( std::string cId) +{ + mBlogId = cId; + + updateChannelMsgs(); +} + +void BlogsDialog::selectChannel(const QModelIndex &index) +{ + int row = index.row(); + int col = index.column(); + if (col != 1) { + QModelIndex sibling = index.sibling(row, 1); + if (sibling.isValid()) + mBlogId = sibling.data().toString().toStdString(); + } else + mBlogId = index.data().toString().toStdString(); + updateChannelMsgs(); +} + +void BlogsDialog::checkUpdate() +{ + std::list blogIds; + std::list::iterator it; + if (!rsBlogs) + return; + + if (rsBlogs->blogsChanged(blogIds)) + { + /* update Blogs List */ + updateChannelList(); + + it = std::find(blogIds.begin(), blogIds.end(), mBlogId); + if (it != blogIds.end()) + { + updateChannelMsgs(); + } + } +} + + +void BlogsDialog::updateChannelList() +{ + + std::list channelList; + std::list::iterator it; + if (!rsBlogs) + { + return; + } + + rsBlogs->getBlogList(channelList); + + /* get the ids for our lists */ + std::list adminIds; + std::list subIds; + std::list popIds; + std::list otherIds; + std::multimap popMap; + + for(it = channelList.begin(); it != channelList.end(); it++) + { + /* sort it into Publish (Own), Subscribed, Popular and Other */ + uint32_t flags = it->blogFlags; + + if (flags & RS_DISTRIB_ADMIN) + { + adminIds.push_back(it->blogId); + } + else if (flags & RS_DISTRIB_SUBSCRIBED) + { + subIds.push_back(it->blogId); + } + else + { + /* rate the others by popularity */ + popMap.insert(std::make_pair(it->pop, it->blogId)); + } + } + + /* iterate backwards through popMap - take the top 5 or 10% of list */ + uint32_t popCount = 5; + if (popCount < popMap.size() / 10) + { + popCount = popMap.size() / 10; + } + + uint32_t i = 0; + uint32_t popLimit = 0; + std::multimap::reverse_iterator rit; + for(rit = popMap.rbegin(); ((rit != popMap.rend()) && (i < popCount)); rit++, i++) + { + popIds.push_back(rit->second); + } + + if (rit != popMap.rend()) + { + popLimit = rit->first; + } + + for(it = channelList.begin(); it != channelList.end(); it++) + { + /* ignore the ones we've done already */ + uint32_t flags = it->blogFlags; + + if (flags & RS_DISTRIB_ADMIN) + { + continue; + } + else if (flags & RS_DISTRIB_SUBSCRIBED) + { + continue; + } + else + { + if (it->pop < popLimit) + { + otherIds.push_back(it->blogId); + } + } + } + + /* now we have our lists ---> update entries */ + + updateChannelListOwn(adminIds); + updateChannelListSub(subIds); + updateChannelListPop(popIds); + updateChannelListOther(otherIds); +} + +void BlogsDialog::updateChannelListOwn(std::list &ids) +{ + std::list::iterator iit; + + /* remove rows with groups before adding new ones */ + model->item(OWN)->removeRows(0, model->item(OWN)->rowCount()); + + for (iit = ids.begin(); iit != ids.end(); iit ++) { +#ifdef CHAN_DEBUG + std::cerr << "BlogsDialog::updateChannelListOwn(): " << *iit << std::endl; +#endif + QStandardItem *ownGroup = model->item(OWN); + QList channel; + QStandardItem *item1 = new QStandardItem(); + QStandardItem *item2 = new QStandardItem(); + + BlogInfo ci; + if (rsBlogs && rsBlogs->getBlogInfo(*iit, ci)) { + item1->setData(QVariant(QString::fromStdWString(ci.blogName)), Qt::DisplayRole); + item2->setData(QVariant(QString::fromStdString(ci.blogId)), Qt::DisplayRole); + item1->setToolTip(tr("Popularity: %1\nFetches: %2\nAvailable: %3" + ).arg(QString::number(ci.pop)).arg(9999).arg(9999)); + } else { + item1->setData(QVariant(QString("Unknown Blog")), Qt::DisplayRole); + item2->setData(QVariant(QString::fromStdString(*iit)), Qt::DisplayRole); + item1->setToolTip("Unknown Blog\nNo Description"); + } + + channel.append(item1); + channel.append(item2); + ownGroup->appendRow(channel); + } +} + +void BlogsDialog::updateChannelListSub(std::list &ids) +{ + std::list::iterator iit; + + /* remove rows with groups before adding new ones */ + model->item(SUBSCRIBED)->removeRows(0, model->item(SUBSCRIBED)->rowCount()); + + for (iit = ids.begin(); iit != ids.end(); iit ++) { +#ifdef CHAN_DEBUG + std::cerr << "BlogsDialog::updateChannelListSub(): " << *iit << std::endl; +#endif + QStandardItem *ownGroup = model->item(SUBSCRIBED); + QList channel; + QStandardItem *item1 = new QStandardItem(); + QStandardItem *item2 = new QStandardItem(); + + BlogInfo ci; + if (rsBlogs && rsBlogs->getBlogInfo(*iit, ci)) { + item1->setData(QVariant(QString::fromStdWString(ci.blogName)), Qt::DisplayRole); + item2->setData(QVariant(QString::fromStdString(ci.blogId)), Qt::DisplayRole); + item1->setToolTip(tr("Popularity: %1\nFetches: %2\nAvailable: %3" + ).arg(QString::number(ci.pop)).arg(9999).arg(9999)); + } else { + item1->setData(QVariant(QString("Unknown Channel")), Qt::DisplayRole); + item2->setData(QVariant(QString::fromStdString(*iit)), Qt::DisplayRole); + item1->setToolTip("Unknown Channel\nNo Description"); + } + + channel.append(item1); + channel.append(item2); + ownGroup->appendRow(channel); + } + +} + +void BlogsDialog::updateChannelListPop(std::list &ids) +{ + std::list::iterator iit; + + /* remove rows with groups before adding new ones */ + model->item(POPULAR)->removeRows(0, model->item(POPULAR)->rowCount()); + + for (iit = ids.begin(); iit != ids.end(); iit ++) { +#ifdef CHAN_DEBUG + std::cerr << "BlogsDialog::updateChannelListPop(): " << *iit << std::endl; +#endif + QStandardItem *ownGroup = model->item(POPULAR); + QList channel; + QStandardItem *item1 = new QStandardItem(); + QStandardItem *item2 = new QStandardItem(); + + BlogInfo ci; + if (rsBlogs && rsBlogs->getBlogInfo(*iit, ci)) { + item1->setData(QVariant(QString::fromStdWString(ci.blogName)), Qt::DisplayRole); + item2->setData(QVariant(QString::fromStdString(ci.blogId)), Qt::DisplayRole); + item1->setToolTip(tr("Popularity: %1\nFetches: %2\nAvailable: %3" + ).arg(QString::number(ci.pop)).arg(9999).arg(9999)); + } else { + item1->setData(QVariant(QString("Unknown Channel")), Qt::DisplayRole); + item2->setData(QVariant(QString::fromStdString(*iit)), Qt::DisplayRole); + item1->setToolTip("Unknown Channel\nNo Description"); + } + + channel.append(item1); + channel.append(item2); + ownGroup->appendRow(channel); + } +} + +void BlogsDialog::updateChannelListOther(std::list &ids) +{ + std::list::iterator iit; + + /* remove rows with groups before adding new ones */ + model->item(OTHER)->removeRows(0, model->item(OTHER)->rowCount()); + + for (iit = ids.begin(); iit != ids.end(); iit ++) { +#ifdef CHAN_DEBUG + std::cerr << "BlogsDialog::updateChannelListOther(): " << *iit << std::endl; +#endif + QStandardItem *ownGroup = model->item(OTHER); + QList channel; + QStandardItem *item1 = new QStandardItem(); + QStandardItem *item2 = new QStandardItem(); + + BlogInfo ci; + if (rsBlogs && rsBlogs->getBlogInfo(*iit, ci)) { + item1->setData(QVariant(QString::fromStdWString(ci.blogName)), Qt::DisplayRole); + item2->setData(QVariant(QString::fromStdString(ci.blogId)), Qt::DisplayRole); + item1->setToolTip(tr("Popularity: %1\nFetches: %2\nAvailable: %3" + ).arg(QString::number(ci.pop)).arg(9999).arg(9999)); + } else { + item1->setData(QVariant(QString("Unknown Blog")), Qt::DisplayRole); + item2->setData(QVariant(QString::fromStdString(*iit)), Qt::DisplayRole); + item1->setToolTip("Unknown Blog\nNo Description"); + } + + channel.append(item1); + channel.append(item2); + ownGroup->appendRow(channel); + } +} + +void BlogsDialog::updateChannelMsgs() +{ + if (!rsBlogs) + return; + + BlogInfo ci; + if (!rsBlogs->getBlogInfo(mBlogId, ci)) + { + postButton->setEnabled(false); + subscribeButton->setEnabled(false); + unsubscribeButton->setEnabled(false); + nameLabel->setText("No Blog Selected"); + iconLabel->setEnabled(false); + return; + } + + iconLabel->setEnabled(true); + + /* set textcolor for Blog name */ + QString channelStr("%1"); + + /* set Blog name */ + QString cname = QString::fromStdWString(ci.blogName); + nameLabel->setText(channelStr.arg(cname)); + + /* do buttons */ + if (ci.blogFlags & RS_DISTRIB_SUBSCRIBED) + { + subscribeButton->setEnabled(false); + unsubscribeButton->setEnabled(true); + } + else + { + subscribeButton->setEnabled(true); + unsubscribeButton->setEnabled(false); + } + + if (ci.blogFlags & RS_DISTRIB_PUBLISH) + { + postButton->setEnabled(true); + } + else + { + postButton->setEnabled(false); + } + + /* replace all the messages with new ones */ + std::list::iterator mit; + for(mit = mBlogMsgItems.begin(); mit != mBlogMsgItems.end(); mit++) + { + delete (*mit); + } + mBlogMsgItems.clear(); + + std::list msgs; + std::list::iterator it; + + rsBlogs->getBlogMsgList(mBlogId, msgs); + + for(it = msgs.begin(); it != msgs.end(); it++) + { + BlogsMsgItem *cmi = new BlogsMsgItem(this, 0, mPeerId, mBlogId, it->msgId, true); + + mBlogMsgItems.push_back(cmi); + verticalLayout_2->addWidget(cmi); + } +} + + +void BlogsDialog::unsubscribeChannel() +{ +#ifdef BLOG_DEBUG + std::cerr << "BlogsDialog::unsubscribeChannel()"; + std::cerr << std::endl; +#endif + if (rsBlogs) + { + rsBlogs->blogSubscribe(mBlogId, false); + } + updateChannelMsgs(); +} + + +void BlogsDialog::subscribeChannel() +{ +#ifdef BLOG_DEBUG + std::cerr << "BlogsDialog::subscribeChannel()"; + std::cerr << std::endl; +#endif + if (rsBlogs) + { + rsBlogs->blogSubscribe(mBlogId, true); + } + updateChannelMsgs(); +} + + +void BlogsDialog::toggleSelection(const QModelIndex &index) +{ + QItemSelectionModel *selectionModel = treeView->selectionModel(); + if (index.child(0, 0).isValid()) + selectionModel->select(index, QItemSelectionModel::Toggle); +} + +void BlogsDialog::showChannelDetails() +{ + if (mBlogId == "") + { + return; + } + + if (!rsBlogs) + return; + + //static ChannelDetails *channelui = new ChannelDetails(); + + //channelui->showDetails(mBlogId); + //channelui->show(); + +} diff --git a/retroshare-gui/src/gui/unfinished/blogs/BlogsDialog.h b/retroshare-gui/src/gui/unfinished/blogs/BlogsDialog.h new file mode 100644 index 000000000..29ef9b628 --- /dev/null +++ b/retroshare-gui/src/gui/unfinished/blogs/BlogsDialog.h @@ -0,0 +1,108 @@ +/**************************************************************** + * RetroShare is distributed under the following license: + * + * Copyright (C) 2008 Robert Fernie + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + +#ifndef _BLOGSDIALOG_H +#define _BLOGSDIALOG_H + +#include "gui/mainpage.h" +#include "ui_BlogsDialog.h" + +#include + +#include "gui/feeds/FeedHolder.h" + +#define OWN 0 +#define SUBSCRIBED 1 +#define POPULAR 2 +#define OTHER 3 + +class BlogsMsgItem; + + +class BlogsDialog : public MainPage, public FeedHolder, private Ui::BlogsDialog +{ + Q_OBJECT + +public: + /** Default Constructor */ + BlogsDialog(QWidget *parent = 0); + /** Default Destructor */ + + +virtual void deleteFeedItem(QWidget *item, uint32_t type); +virtual void openChat(std::string peerId); +virtual void openMsg(uint32_t type, std::string grpId, std::string inReplyTo); + +public slots: + + void selectChannel( std::string ); + void selectChannel(const QModelIndex &); + void toggleSelection(const QModelIndex &); + +private slots: + + void channelListCustomPopupMenu( QPoint point ); + + void checkUpdate(); + + void createChannel(); + //void sendMsg(); + + void channelSelection(); + + void subscribeChannel(); + void unsubscribeChannel(); + + void createMsg(); + + void showChannelDetails(); + +private: + + void updateChannelList(); + void updateChannelListOwn(std::list &ids); + void updateChannelListSub(std::list &ids); + void updateChannelListPop(std::list &ids); + void updateChannelListOther(std::list &ids); + + void updateChannelMsgs(); + + QStandardItemModel *model; + + std::string mBlogId; /* current Channel */ + std::string mPeerId; + + /* Layout Pointers */ + QBoxLayout *mMsgLayout; + + + + std::list mBlogMsgItems; + + QFont mChannelFont; + QFont itemFont; + +}; + + + +#endif + diff --git a/retroshare-gui/src/gui/unfinished/blogs/BlogsDialog.ui b/retroshare-gui/src/gui/unfinished/blogs/BlogsDialog.ui new file mode 100644 index 000000000..168de854d --- /dev/null +++ b/retroshare-gui/src/gui/unfinished/blogs/BlogsDialog.ui @@ -0,0 +1,590 @@ + + + BlogsDialog + + + + 0 + 0 + 681 + 476 + + + + + 0 + 0 + + + + + 0 + 0 + + + + Form + + + + + + + 0 + 0 + + + + + 222 + 0 + + + + + 222 + 16777215 + + + + + 0 + 0 + + + + + 221 + 0 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + + + + 220 + 0 + + + + + 220 + 16777215 + + + + + 220 + 0 + + + + QFrame#chheaderframe{ +background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, + stop:0 #FEFEFE, stop:1 #E8E8E8); + +border: 1px solid #CCCCCC;} + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 2 + + + + + 0 + + + + + + 24 + 24 + + + + + + + :/images/kblogger.png + + + true + + + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Arial'; font-size:10pt; font-weight:600;">Blogs</span></p></body></html> + + + + + + + + + Qt::Horizontal + + + + 123 + 13 + + + + + + + + Add + + + QPushButton::menu-indicator { + subcontrol-origin: padding; + subcontrol-position: bottom right; + } + + QPushButton::menu-indicator:pressed, QPushButton::menu-indicator:open { + position: relative; + top: 2px; left: 2px; /* shift the arrow by 2 px */ + } + + QPushButton:hover { + border: 1px solid #CCCCCC; + } + + + + + + + :/images/edit_add24.png:/images/edit_add24.png + + + + 16 + 16 + + + + false + + + true + + + + + + + + + + Qt::CustomContextMenu + + + + + + + + + + + + QFrame#frame{ +border: 2px solid #6ACEFF; +border-radius: 10px; +background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, + stop:0 #0076B1, stop:1 #12A3EB);} + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + + + 16 + + + 9 + + + + + + 64 + 64 + + + + + 64 + 64 + + + + QLabel{ +border: 2px solid white; +border-radius: 10px; +} + + + + + + :/images/hi64-app-kblogger.png + + + false + + + Qt::AlignCenter + + + + + + + + 75 + true + + + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:600; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:14pt; color:#ffffff;">Blog Name</span></p></body></html> + + + true + + + + + + + + + Qt::Horizontal + + + + + + + 9 + + + 9 + + + + + + 0 + 0 + + + + + 0 + 25 + + + + Post To Channel + + + QToolButton, QPushButton, QComboBox { +border-image: url(:/images/btn_26.png) 4; +border-width: 4; +padding: 0px 6px; +font-size: 12px; +} + +QToolButton:hover, QPushButton:hover, QComboBox:hover { +border-image: url(:/images/btn_26_hover.png) 4; +} + +QToolButton:disabled, QPushButton:disabled, QComboBox::disabled { +color:gray; +} + +QToolButton:pressed, QPushButton:pressed{ +border-image: url(:/images/btn_26_pressed.png) 4; +} + + + + + + + :/images/mail_send.png:/images/mail_send.png + + + + + + + + 0 + 0 + + + + + 26 + 26 + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:9pt;">Unsubcribe To Blog</span></p></body></html> + + + QToolButton, QPushButton, QComboBox { +border-image: url(:/images/btn_26.png) 4; +border-width: 4; +padding: 0px 6px; +font-size: 12px; +} + +QToolButton:hover, QPushButton:hover, QComboBox:hover { +border-image: url(:/images/btn_26_hover.png) 4; +} + +QToolButton:disabled, QPushButton:disabled, QComboBox::disabled { +color:gray; +} + +QToolButton:pressed, QPushButton:pressed{ +border-image: url(:/images/btn_26_pressed.png) 4; +} + + + Unsubscribe + + + + + + + + 0 + 0 + + + + + 26 + 26 + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:9pt;">Subscribe To Blog</span></p></body></html> + + + QToolButton, QPushButton, QComboBox { +border-image: url(:/images/btn_26.png) 4; +border-width: 4; +padding: 0px 6px; +font-size: 12px; +} + +QToolButton:hover, QPushButton:hover, QComboBox:hover { +border-image: url(:/images/btn_26_hover.png) 4; +} + +QToolButton:disabled, QPushButton:disabled, QComboBox::disabled { +color:gray; +} + +QToolButton:pressed, QPushButton:pressed{ +border-image: url(:/images/btn_26_pressed.png) 4; +} + + + Subscribe + + + + :/images/konqsidebar_news24.png:/images/konqsidebar_news24.png + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + 1 + 0 + + + + + 0 + 0 + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + + + true + + + Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft + + + + + 0 + 0 + 429 + 329 + + + + QWidget#scrollAreaWidgetContents{border: none;} + + + + 0 + + + 0 + + + + + + + + Qt::Vertical + + + + 391 + 266 + + + + + + + + + + + + + + + + + + :/images/kblogger.png:/images/kblogger.png + + + Create New Blog + + + Create New Blog + + + + + + + + + + + + + + + diff --git a/retroshare-gui/src/gui/unfinished/blogs/BlogsMsgItem.cpp b/retroshare-gui/src/gui/unfinished/blogs/BlogsMsgItem.cpp new file mode 100644 index 000000000..ac1fc7152 --- /dev/null +++ b/retroshare-gui/src/gui/unfinished/blogs/BlogsMsgItem.cpp @@ -0,0 +1,235 @@ +/**************************************************************** + * RetroShare is distributed under the following license: + * + * Copyright (C) 2008 Robert Fernie + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ +#include +#include + +#include "BlogsMsgItem.h" + +#include "gui/feeds/FeedHolder.h" +#include "gui/feeds/SubFileItem.h" + +#include "rsiface/rsblogs.h" + +#include +#include + + +/**** + * #define DEBUG_ITEM 1 + ****/ + +/** Constructor */ +BlogsMsgItem::BlogsMsgItem(FeedHolder *parent, uint32_t feedId, std::string peerId, std::string blogId, std::string msgId, bool isHome) +:QWidget(NULL), mParent(parent), mFeedId(feedId), + mPeerId(peerId), mBlogId(blogId), mMsgId(msgId), mIsHome(isHome) +{ + /* Invoke the Qt Designer generated object setup routine */ + setupUi(this); + + /* general ones */ + connect( expandButton, SIGNAL( clicked( void ) ), this, SLOT( toggle ( void ) ) ); + connect( clearButton, SIGNAL( clicked( void ) ), this, SLOT( removeItem ( void ) ) ); + //connect( gotoButton, SIGNAL( clicked( void ) ), this, SLOT( gotoHome ( void ) ) ); + + /* specific ones */ + //connect( playButton, SIGNAL( clicked( void ) ), this, SLOT( playMedia ( void ) ) ); + connect( unsubscribeButton, SIGNAL( clicked( void ) ), this, SLOT( unsubscribeChannel ( void ) ) ); + + small(); + updateItemStatic(); + updateItem(); + +} + + +void BlogsMsgItem::updateItemStatic() +{ + /* fill in */ +#ifdef DEBUG_ITEM + std::cerr << "ChanMsgItem::updateItemStatic()"; + std::cerr << std::endl; +#endif + + BlogMsgInfo cmi; + + if (!rsBlogs) + return; + + if (!rsBlogs->getBlogMessage(mBlogId, mMsgId, cmi)) + return; + + QString title; + + if (!mIsHome) + { + BlogInfo ci; + rsBlogs->getBlogInfo(mBlogId, ci); + title = "Channel Feed: "; + title += QString::fromStdWString(ci.blogName); + titleLabel->setText(title); + //subjectLabel->setText(QString::fromStdWString(cmi.subject)); + } + else + { + /* subject */ + titleLabel->setText(QString::fromStdWString(cmi.subject)); + /* Blog Message */ + textBrowser->setHtml( QString::fromStdWString(cmi.msg)); + } + + //msgLabel->setText(QString::fromStdWString(cmi.msg)); + //msgcommentstextEdit->setHtml(QString::fromStdWString(cmi.msg)); + + QDateTime qtime; + qtime.setTime_t(cmi.ts); + QString timestamp = qtime.toString("dd.MMMM yyyy hh:mm:ss"); + datetimelabel->setText(timestamp); + + + + std::list::iterator it; + for(it = cmi.files.begin(); it != cmi.files.end(); it++) + { + /* add file */ + SubFileItem *fi = new SubFileItem(it->hash, it->fname, it->size, + SFI_STATE_REMOTE | SFI_TYPE_CHANNEL, ""); + mFileItems.push_back(fi); + + QLayout *layout = expandFrame->layout(); + layout->addWidget(fi); + } + + //playButton->setEnabled(false); + + if (mIsHome) + { + /* disable buttons */ + clearButton->setEnabled(false); + //gotoButton->setEnabled(false); + unsubscribeButton->setEnabled(false); + + clearButton->hide(); + } + + /* don't really want this at all! */ + unsubscribeButton->hide(); + //playButton->hide(); +} + + +void BlogsMsgItem::updateItem() +{ + /* fill in */ +#ifdef DEBUG_ITEM + std::cerr << "ChanMsgItem::updateItem()"; + std::cerr << std::endl; +#endif + int msec_rate = 10000; + + /* Very slow Tick to check when all files are downloaded */ + std::list::iterator it; + for(it = mFileItems.begin(); it != mFileItems.end(); it++) + { + if (!(*it)->done()) + { + /* loop again */ + QTimer::singleShot( msec_rate, this, SLOT(updateItem( void ) )); + return; + } + } + + /*** + * At this point cannot create a playlist.... + * so can't enable play for all. + + if (mFileItems.size() > 0) + { + playButton->setEnabled(true); + } + ***/ +} + + +void BlogsMsgItem::small() +{ + expandFrame->hide(); +} + +void BlogsMsgItem::toggle() +{ + if (expandFrame->isHidden()) + { + expandFrame->show(); + expandButton->setIcon(QIcon(QString(":/images/edit_remove24.png"))); + expandButton->setToolTip(tr("Hide")); + } + else + { + expandFrame->hide(); + expandButton->setIcon(QIcon(QString(":/images/edit_add24.png"))); + expandButton->setToolTip(tr("Expand")); + } +} + + +void BlogsMsgItem::removeItem() +{ +#ifdef DEBUG_ITEM + std::cerr << "ChanMsgItem::removeItem()"; + std::cerr << std::endl; +#endif + hide(); + if (mParent) + { + mParent->deleteFeedItem(this, mFeedId); + } +} + + +void BlogsMsgItem::gotoHome() +{ +#ifdef DEBUG_ITEM + std::cerr << "ChanMsgItem::gotoHome()"; + std::cerr << std::endl; +#endif +} + +/*********** SPECIFIC FUNCTIOSN ***********************/ + + +void BlogsMsgItem::unsubscribeChannel() +{ +#ifdef DEBUG_ITEM + std::cerr << "ChanMsgItem::unsubscribeChannel()"; + std::cerr << std::endl; +#endif +} + + +void BlogsMsgItem::playMedia() +{ +#ifdef DEBUG_ITEM + std::cerr << "ChanMsgItem::playMedia()"; + std::cerr << std::endl; +#endif +} + + diff --git a/retroshare-gui/src/gui/unfinished/blogs/BlogsMsgItem.h b/retroshare-gui/src/gui/unfinished/blogs/BlogsMsgItem.h new file mode 100644 index 000000000..58a135080 --- /dev/null +++ b/retroshare-gui/src/gui/unfinished/blogs/BlogsMsgItem.h @@ -0,0 +1,73 @@ +/**************************************************************** + * RetroShare is distributed under the following license: + * + * Copyright (C) 2008 Robert Fernie + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + +#ifndef _BLOGS_MSG_ITEM_DIALOG_H +#define _BLOGS_MSG_ITEM_DIALOG_H + +#include "ui_BlogsMsgItem.h" + +#include +#include + +class FeedHolder; +class SubFileItem; + +class BlogsMsgItem : public QWidget, private Ui::BlogsMsgItem +{ + Q_OBJECT + +public: + /** Default Constructor */ + BlogsMsgItem(FeedHolder *parent, uint32_t feedId, std::string peerId, std::string blogId, std::string msgId, bool isHome); + + /** Default Destructor */ + + void updateItemStatic(); + void small(); + +private slots: + /* default stuff */ + void gotoHome(); + void removeItem(); + void toggle(); + + void playMedia(); + void unsubscribeChannel(); + + void updateItem(); + +private: + FeedHolder *mParent; + uint32_t mFeedId; + + std::string mBlogId; + std::string mMsgId; + std::string mPeerId; + + bool mIsHome; + + std::list mFileItems; +}; + + + +#endif + diff --git a/retroshare-gui/src/gui/unfinished/blogs/BlogsMsgItem.ui b/retroshare-gui/src/gui/unfinished/blogs/BlogsMsgItem.ui new file mode 100644 index 000000000..7c8fcb40d --- /dev/null +++ b/retroshare-gui/src/gui/unfinished/blogs/BlogsMsgItem.ui @@ -0,0 +1,265 @@ + + + BlogsMsgItem + + + + 0 + 0 + 516 + 327 + + + + Form + + + QToolButton, QPushButton, QComboBox { +border-image: url(:/images/btn_26.png) 4; +border-width: 4; +padding: 0px 6px; +font-size: 12px; +} + +QToolButton:hover, QPushButton:hover, QComboBox:hover { +border-image: url(:/images/btn_26_hover.png) 4; +} + +QToolButton:disabled, QPushButton:disabled, QComboBox::disabled { +color:gray; +} + +QToolButton:pressed, QPushButton:pressed{ +border-image: url(:/images/btn_26_pressed.png) 4; +} + + + + 0 + + + 6 + + + + + + 0 + 0 + + + + QFrame#frame{border: 3px solid #407AC1; +background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, +stop:0 #FFFFFF, stop:1 #F2F2F2);; +border-radius: 10px;} + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + QFrame#expandFrame{border: 2px solid #D3D3D3; +background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, +stop:0 #FFFFFF, stop:1 #F2F2F2);; +border-radius: 10px;} + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + 0 + 0 + + + + Comments here + + + + + + + + + + + + + 0 + 0 + + + + + 11 + 75 + true + true + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:11pt; font-weight:600; font-style:italic;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" color:#656565;">Blog Subject</span></p></body></html> + + + + + + + + 75 + true + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:600; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; color:#666666;">DateTime</span></p></body></html> + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 288 + 21 + + + + + + + + + 0 + 0 + + + + Expand + + + + + + + + + + :/images/edit_add24.png:/images/edit_add24.png + + + + + + + + 0 + 0 + + + + Remove Item + + + + + + + :/images/close_normal.png:/images/close_normal.png + + + + + + + + 0 + 0 + + + + Unsubscribe From Channel + + + + + + + :/images/mail_delete.png:/images/mail_delete.png + + + + + + + + 0 + 0 + + + + QTextBrowser#textBrowser{border: 2px solid #D3D3D3; +background-color: transparent; +border-radius: 10px;} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/retroshare-gui/src/gui/unfinished/blogs/CreateBlog.cpp b/retroshare-gui/src/gui/unfinished/blogs/CreateBlog.cpp new file mode 100644 index 000000000..6a72fbbac --- /dev/null +++ b/retroshare-gui/src/gui/unfinished/blogs/CreateBlog.cpp @@ -0,0 +1,138 @@ +/**************************************************************** + * RetroShare is distributed under the following license: + * + * Copyright (C) 2008 Robert Fernie + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + +#include +#include + +#include "CreateBlog.h" + +#include "rsiface/rsblogs.h" + +/** Constructor */ +CreateBlog::CreateBlog(QWidget *parent, bool isForum) +: QDialog(parent), mIsForum(isForum) +{ + /* Invoke the Qt Designer generated object setup routine */ + ui.setupUi(this); + + // connect up the buttons. + connect( ui.cancelButton, SIGNAL( clicked ( bool ) ), this, SLOT( cancelBlog( ) ) ); + connect( ui.createButton, SIGNAL( clicked ( bool ) ), this, SLOT( createBlog( ) ) ); + + + newBlog(); + +} + +void CreateBlog::show() +{ + //loadSettings(); + if(!this->isVisible()) { + QWidget::show(); + + } +} + + +void CreateBlog::newBlog() +{ + + if (mIsForum) + { + /* enforce Public for the moment */ + ui.typePublic->setChecked(true); + + ui.typePrivate->setEnabled(false); + ui.typeEncrypted->setEnabled(false); + + ui.msgAnon->setChecked(true); + //ui.msgAuth->setEnabled(false); + } + else + { + /* enforce Private for the moment */ + ui.typePrivate->setChecked(true); + + ui.typePublic->setEnabled(false); + ui.typeEncrypted->setEnabled(false); + + ui.msgAnon->setChecked(true); + ui.msgAuth->setEnabled(false); + ui.msgGroupBox->hide(); + } +} + +void CreateBlog::createBlog() +{ + QString name = ui.forumName->text(); + QString desc = ui.forumDesc->toPlainText(); //toHtml(); + uint32_t flags = 0; + + if(name.isEmpty()) + { /* error message */ + int ret = QMessageBox::warning(this, tr("RetroShare"), + tr("Please add a Name"), + QMessageBox::Ok, QMessageBox::Ok); + + return; //Don't add a empty name!! + } + else + + if (ui.typePublic->isChecked()) + { + flags |= RS_DISTRIB_PUBLIC; + } + else if (ui.typePrivate->isChecked()) + { + flags |= RS_DISTRIB_PRIVATE; + } + else if (ui.typeEncrypted->isChecked()) + { + flags |= RS_DISTRIB_ENCRYPTED; + } + + if (ui.msgAuth->isChecked()) + { + flags |= RS_DISTRIB_AUTHEN_REQ; + } + else if (ui.msgAnon->isChecked()) + { + flags |= RS_DISTRIB_AUTHEN_ANON; + } + + if (rsBlogs) + { + rsBlogs->createBlog(name.toStdWString(), desc.toStdWString(), flags); + } + + + close(); + return; +} + + +void CreateBlog::cancelBlog() +{ + close(); + return; +} + + diff --git a/retroshare-gui/src/gui/unfinished/blogs/CreateBlog.h b/retroshare-gui/src/gui/unfinished/blogs/CreateBlog.h new file mode 100644 index 000000000..2b9e1578b --- /dev/null +++ b/retroshare-gui/src/gui/unfinished/blogs/CreateBlog.h @@ -0,0 +1,61 @@ +/**************************************************************** + * RetroShare is distributed under the following license: + * + * Copyright (C) 2008 Robert Fernie + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + +#ifndef _CREATE_BLOG_DIALOG_H +#define _CREATE_BLOG_DIALOG_H + +#include + +#include "ui_CreateBlog.h" + +class CreateBlog : public QDialog +{ + Q_OBJECT + +public: + CreateBlog(QWidget *parent = 0, bool isForum = true); + +void newBlog(); /* cleanup */ + + /** Qt Designer generated object */ + Ui::CreateBlog ui; + + QPixmap picture; + +public slots: + /** Overloaded QWidget.show */ + void show(); + +private slots: + + /* actions to take.... */ +void createBlog(); +void cancelBlog(); + + +private: + + + bool mIsForum; +}; + +#endif + diff --git a/retroshare-gui/src/gui/unfinished/blogs/CreateBlog.ui b/retroshare-gui/src/gui/unfinished/blogs/CreateBlog.ui new file mode 100644 index 000000000..6c789e907 --- /dev/null +++ b/retroshare-gui/src/gui/unfinished/blogs/CreateBlog.ui @@ -0,0 +1,245 @@ + + + CreateBlog + + + + 0 + 0 + 534 + 481 + + + + Create new Blog + + + + :/images/rstray3.png:/images/rstray3.png + + + + 0 + + + 0 + + + + + + 16777215 + 64 + + + + QFrame#frame_2{background-image: url(:/images/connect/connectFriendBanner.png);} + + + QFrame::NoFrame + + + QFrame::Raised + + + + 6 + + + 6 + + + + + + 48 + 48 + + + + + + + + + + :/images/hi48-app-kblogger.png + + + true + + + + + + + color: rgb(255, 255, 255); + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Arial'; font-size:24pt; font-weight:600; color:#ffffff;">New Blog</span></p></body></html> + + + + + + + + + + QFrame::NoFrame + + + QFrame::Raised + + + + + + + + Name + + + + + + + + + + + + + + Description + + + + + + + + + + + + Type: + + + + 0 + + + 6 + + + + + Public - Anyone can read and publish (Shared Publish Key) + + + + + + + Restricted - Anyone can read, limited publishing (Private Publish Key) + + + + + + + Private - (Private Publish Key required to view Messages) + + + + + + + + + + Allowed Messages + + + + 0 + + + 6 + + + + + Authemticated Messages + + + + + + + Anonymous Messages + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + Qt::Horizontal + + + + 238 + 20 + + + + + + + + Cancel + + + + + + + Create + + + true + + + + + + + + + + + + + + diff --git a/retroshare-gui/src/gui/unfinished/blogs/CreateBlogMsg.cpp b/retroshare-gui/src/gui/unfinished/blogs/CreateBlogMsg.cpp new file mode 100644 index 000000000..d095fdfcd --- /dev/null +++ b/retroshare-gui/src/gui/unfinished/blogs/CreateBlogMsg.cpp @@ -0,0 +1,1282 @@ +/**************************************************************** + * RetroShare is distributed under the following license: + * + * Copyright (C) 2008 Robert Fernie + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ +#include +//#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "CreateBlogMsg.h" + +#include "gui/feeds/SubFileItem.h" +#include "gui/msgs/textformat.h" + +#include "rsiface/rstypes.h" +#include "rsiface/rspeers.h" +#include "rsiface/rsforums.h" +#include "rsiface/rsblogs.h" +#include "rsiface/rsmsgs.h" +#include "rsiface/rsfiles.h" + +#include + +/** Constructor */ +CreateBlogMsg::CreateBlogMsg(std::string cId ,QWidget* parent, Qt::WFlags flags) +: mBlogId(cId), QMainWindow (parent, flags) ,mCheckAttachment(true) +{ + /* Invoke the Qt Designer generated object setup routine */ + ui.setupUi(this); + + setupFileActions(); + setupEditActions(); + setupViewActions(); + setupInsertActions(); + setupParagraphActions(); + + setAcceptDrops(true); + setStartupText(); + + newBlogMsg(); + + ui.toolBar_2->addAction(ui.actionIncreasefontsize); + ui.toolBar_2->addAction(ui.actionDecreasefontsize); + ui.toolBar_2->addAction(ui.actionBlockquoute); + ui.toolBar_2->addAction(ui.actionOrderedlist); + ui.toolBar_2->addAction(ui.actionUnorderedlist); + ui.toolBar_2->addAction(ui.actionBlockquoute); + ui.toolBar_2->addAction(ui.actionCode); + ui.toolBar_2->addAction(ui.actionsplitPost); + + setupTextActions(); + + connect(ui.actionPublish, SIGNAL(triggered()), this, SLOT(sendMsg())); + connect(ui.actionNew, SIGNAL(triggered()), this, SLOT (fileNew())); + + connect(ui.addFileButton, SIGNAL(clicked() ), this , SLOT(addExtraFile())); + + connect(ui.actionIncreasefontsize, SIGNAL (triggered()), this, SLOT (fontSizeIncrease())); + connect(ui.actionDecreasefontsize, SIGNAL (triggered()), this, SLOT (fontSizeDecrease())); + connect(ui.actionBlockquoute, SIGNAL (triggered()), this, SLOT (blockQuote())); + connect(ui.actionCode, SIGNAL (triggered()), this, SLOT (toggleCode())); + connect(ui.actionsplitPost, SIGNAL (triggered()), this, SLOT (addPostSplitter())); + connect(ui.actionOrderedlist, SIGNAL (triggered()), this, SLOT (addOrderedList())); + connect(ui.actionUnorderedlist, SIGNAL (triggered()), this, SLOT (addUnorderedList())); + + //connect(webView, SIGNAL(loadFinished(bool)),this, SLOT(updateTextEdit())); + connect( ui.msgEdit, SIGNAL( textChanged(const QString &)), this, SLOT(updateTextEdit())); + + connect( ui.msgEdit, SIGNAL(currentCharFormatChanged(QTextCharFormat)), + this, SLOT(currentCharFormatChanged(QTextCharFormat))); + connect( ui.msgEdit, SIGNAL(cursorPositionChanged()), + this, SLOT(cursorPositionChanged())); + + QPalette palette = QApplication::palette(); + codeBackground = palette.color( QPalette::Active, QPalette::Midlight ); + + fontChanged(ui.msgEdit->font()); + colorChanged(ui.msgEdit->textColor()); + alignmentChanged(ui.msgEdit->alignment()); + + connect( ui.msgEdit->document(), SIGNAL(modificationChanged(bool)), + actionSave, SLOT(setEnabled(bool))); + connect( ui.msgEdit->document(), SIGNAL(modificationChanged(bool)), + this, SLOT(setWindowModified(bool))); + connect( ui.msgEdit->document(), SIGNAL(undoAvailable(bool)), + actionUndo, SLOT(setEnabled(bool))); + connect( ui.msgEdit->document(), SIGNAL(undoAvailable(bool)), + ui.actionUndo, SLOT(setEnabled(bool))); + connect( ui.msgEdit->document(), SIGNAL(redoAvailable(bool)), + actionRedo, SLOT(setEnabled(bool))); + + setWindowModified( ui.msgEdit->document()->isModified()); + actionSave->setEnabled( ui.msgEdit->document()->isModified()); + actionUndo->setEnabled( ui.msgEdit->document()->isUndoAvailable()); + ui.actionUndo->setEnabled( ui.msgEdit->document()->isUndoAvailable()); + actionRedo->setEnabled( ui.msgEdit->document()->isRedoAvailable()); + + connect(actionUndo, SIGNAL(triggered()), ui.msgEdit, SLOT(undo())); + connect(ui.actionUndo, SIGNAL(triggered()), ui.msgEdit, SLOT(undo())); + connect(actionRedo, SIGNAL(triggered()), ui.msgEdit, SLOT(redo())); + + actionCut->setEnabled(false); + actionCopy->setEnabled(false); + + connect(actionCut, SIGNAL(triggered()), ui.msgEdit, SLOT(cut())); + connect(actionCopy, SIGNAL(triggered()), ui.msgEdit, SLOT(copy())); + connect(actionPaste, SIGNAL(triggered()), ui.msgEdit, SLOT(paste())); + + connect(ui.msgEdit, SIGNAL(copyAvailable(bool)), actionCut, SLOT(setEnabled(bool))); + connect(ui.msgEdit, SIGNAL(copyAvailable(bool)), actionCopy, SLOT(setEnabled(bool))); + +#ifndef QT_NO_CLIPBOARD + connect(QApplication::clipboard(), SIGNAL(dataChanged()), this, SLOT(clipboardDataChanged())); +#endif + + //defaultCharFormat + defaultCharFormat = ui.msgEdit->currentCharFormat(); + + const QFont defaultFont = ui.msgEdit->document()->defaultFont(); + defaultCharFormat.setFont( defaultFont ); + defaultCharFormat.setForeground( ui.msgEdit->currentCharFormat().foreground() ); + defaultCharFormat.setProperty( QTextFormat::FontSizeAdjustment, QVariant( 0 ) ); + defaultCharFormat.setBackground( palette.color( QPalette::Active, + QPalette::Base ) ); + defaultCharFormat.setProperty( TextFormat::HasCodeStyle, QVariant( false ) ); + + //defaultBlockFormat + defaultBlockFormat = ui.msgEdit->textCursor().blockFormat(); + +} + +/* Dropping */ + +void CreateBlogMsg::dragEnterEvent(QDragEnterEvent *event) +{ + /* print out mimeType */ + std::cerr << "CreateChannelMsg::dragEnterEvent() Formats"; + std::cerr << std::endl; + QStringList formats = event->mimeData()->formats(); + QStringList::iterator it; + for(it = formats.begin(); it != formats.end(); it++) + { + std::cerr << "Format: " << (*it).toStdString(); + std::cerr << std::endl; + } + + if (event->mimeData()->hasFormat("text/plain")) + { + std::cerr << "CreateChannelMsg::dragEnterEvent() Accepting PlainText"; + std::cerr << std::endl; + event->acceptProposedAction(); + } + else if (event->mimeData()->hasUrls()) + { + std::cerr << "CreateChannelMsg::dragEnterEvent() Accepting Urls"; + std::cerr << std::endl; + event->acceptProposedAction(); + } + else if (event->mimeData()->hasFormat("application/x-rsfilelist")) + { + std::cerr << "CreateChannelMsg::dragEnterEvent() accepting Application/x-qabs..."; + std::cerr << std::endl; + event->acceptProposedAction(); + } + else + { + std::cerr << "CreateChannelMsg::dragEnterEvent() No PlainText/Urls"; + std::cerr << std::endl; + } +} + +void CreateBlogMsg::dropEvent(QDropEvent *event) +{ + if (!(Qt::CopyAction & event->possibleActions())) + { + std::cerr << "CreateChannelMsg::dropEvent() Rejecting uncopyable DropAction"; + std::cerr << std::endl; + + /* can't do it */ + return; + } + + std::cerr << "CreateChannelMsg::dropEvent() Formats"; + std::cerr << std::endl; + QStringList formats = event->mimeData()->formats(); + QStringList::iterator it; + for(it = formats.begin(); it != formats.end(); it++) + { + std::cerr << "Format: " << (*it).toStdString(); + std::cerr << std::endl; + } + + if (event->mimeData()->hasText()) + { + std::cerr << "CreateChannelMsg::dropEvent() Plain Text:"; + std::cerr << std::endl; + std::cerr << event->mimeData()->text().toStdString(); + std::cerr << std::endl; + } + + if (event->mimeData()->hasUrls()) + { + std::cerr << "CreateChannelMsg::dropEvent() Urls:"; + std::cerr << std::endl; + + QList urls = event->mimeData()->urls(); + QList::iterator uit; + for(uit = urls.begin(); uit != urls.end(); uit++) + { + std::string localpath = uit->toLocalFile().toStdString(); + std::cerr << "Whole URL: " << uit->toString().toStdString(); + std::cerr << std::endl; + std::cerr << "or As Local File: " << localpath; + std::cerr << std::endl; + + if (localpath.size() > 0) + { + + addAttachment(localpath); + } + } + } + else if (event->mimeData()->hasFormat("application/x-rsfilelist")) + { + std::cerr << "CreateChannelMsg::dropEvent() Application/x-rsfilelist"; + std::cerr << std::endl; + + + QByteArray data = event->mimeData()->data("application/x-rsfilelist"); + std::cerr << "Data Len:" << data.length(); + std::cerr << std::endl; + std::cerr << "Data is:" << data.data(); + std::cerr << std::endl; + + std::string newattachments(data.data()); + parseRsFileListAttachments(newattachments); + } + + + event->setDropAction(Qt::CopyAction); + event->accept(); +} + +void CreateBlogMsg::parseRsFileListAttachments(std::string attachList) +{ + /* split into lines */ + QString input = QString::fromStdString(attachList); + + QStringList attachItems = input.split("\n"); + QStringList::iterator it; + QStringList::iterator it2; + + for(it = attachItems.begin(); it != attachItems.end(); it++) + { + std::cerr << "CreateBlogMsg::parseRsFileListAttachments() Entry: "; + + QStringList parts = (*it).split("/"); + + bool ok = false; + quint64 qsize = 0; + + std::string fname; + std::string hash; + uint64_t size = 0; + std::string source; + + int i = 0; + for(it2 = parts.begin(); it2 != parts.end(); it2++, i++) + { + std::cerr << "\"" << it2->toStdString() << "\" "; + switch(i) + { + case 0: + fname = it2->toStdString(); + break; + case 1: + hash = it2->toStdString(); + break; + case 2: + qsize = it2->toULongLong(&ok, 10); + size = qsize; + break; + case 3: + source = it2->toStdString(); + break; + } + } + + std::cerr << std::endl; + + std::cerr << "\tfname: " << fname << std::endl; + std::cerr << "\thash: " << hash << std::endl; + std::cerr << "\tsize: " << size << std::endl; + std::cerr << "\tsource: " << source << std::endl; + + /* basic error checking */ + if ((ok) && (hash.size() == 40)) + { + std::cerr << "Item Ok" << std::endl; + if (source == "Local") + { + addAttachment(hash, fname, size, true, ""); + } + else + { + // TEMP NOT ALLOWED UNTIL FT WORKING. + addAttachment(hash, fname, size, false, source); + } + + } + else + { + std::cerr << "Error Decode: Hash size: " << hash.size() << std::endl; + } + + } +} + + +void CreateBlogMsg::addAttachment(std::string hash, std::string fname, uint64_t size, bool local, std::string srcId) +{ + /* add a SubFileItem to the attachment section */ + std::cerr << "CreateChannelMsg::addAttachment()"; + std::cerr << std::endl; + + /* add widget in for new destination */ + + uint32_t flags = SFI_TYPE_ATTACH; + if (local) + { + flags |= SFI_STATE_LOCAL; + } + else + { + flags |= SFI_STATE_REMOTE; + // TMP REMOVED REMOTE ADD FOR DEMONSTRATOR + return; + } + + SubFileItem *file = new SubFileItem(hash, fname, size, flags, srcId); + + mAttachments.push_back(file); + ui.verticalLayout_3->addWidget(file); + + if (mCheckAttachment) + { + checkAttachmentReady(); + } + + return; +} + + +void CreateBlogMsg::addExtraFile() +{ + /* add a SubFileItem to the attachment section */ + std::cerr << "CreateChannelMsg::addExtraFile() opening file dialog"; + std::cerr << std::endl; + + // select a file + QString qfile = QFileDialog::getOpenFileName(this, tr("Add Extra File"), "", "", 0, + QFileDialog::DontResolveSymlinks); + std::string filePath = qfile.toStdString(); + if (filePath != "") + { + addAttachment(filePath); + } +} + + +void CreateBlogMsg::addAttachment(std::string path) +{ + /* add a SubFileItem to the attachment section */ + std::cerr << "CreateChannelMsg::addAttachment()"; + std::cerr << std::endl; + + /* add to ExtraList here, + * use default TIMEOUT of 30 days (time to fetch it). + */ + //uint32_t period = 30 * 24 * 60 * 60; + //uint32_t flags = 0; + //rsFiles->ExtraFileHash(localpath, period, flags); + + /* add widget in for new destination */ + SubFileItem *file = new SubFileItem(path); + + mAttachments.push_back(file); + ui.verticalLayout_3->addWidget(file); + + if (mCheckAttachment) + { + checkAttachmentReady(); + } + + return; + +} + +void CreateBlogMsg::checkAttachmentReady() +{ + std::list::iterator fit; + + mCheckAttachment = false; + + for(fit = mAttachments.begin(); fit != mAttachments.end(); fit++) + { + if (!(*fit)->isHidden()) + { + if (!(*fit)->ready()) + { + /* + */ + ui.actionPublish->setEnabled(false); + break; + + + return; + } + } + } + + if (fit == mAttachments.end()) + { + ui.actionPublish->setEnabled(true); + } + + /* repeat... */ + int msec_rate = 1000; + QTimer::singleShot( msec_rate, this, SLOT(checkAttachmentReady(void))); +} + + +void CreateBlogMsg::cancelMsg() +{ + std::cerr << "CreateBlogMsg::cancelMsg()"; + std::cerr << std::endl; + close(); + return; +} + +void CreateBlogMsg::newBlogMsg() +{ + + if (!rsBlogs) + return; + + BlogInfo ci; + if (!rsBlogs->getBlogInfo(mBlogId, ci)) + { + + return; + } + + ui.channelName->setText(QString::fromStdWString(ci.blogName)); + + + +} + + +void CreateBlogMsg::sendMsg() +{ + std::cerr << "CreateBlogMsg::sendMsg()"; + std::cerr << std::endl; + + /* construct message bits */ + std::wstring subject = ui.subjectEdit->text().toStdWString(); + std::wstring msg = ui.msgEdit->toHtml().toStdWString(); + + std::list files; + + std::list::iterator fit; + + for(fit = mAttachments.begin(); fit != mAttachments.end(); fit++) + { + if (!(*fit)->isHidden()) + { + FileInfo fi; + fi.hash = (*fit)->FileHash(); + fi.fname = (*fit)->FileName(); + fi.size = (*fit)->FileSize(); + + files.push_back(fi); + + /* commence downloads - if we don't have the file */ + if (!(*fit)->done()) + { + if ((*fit)->ready()) + { + (*fit)->download(); + } + // Skips unhashed files. + } + } + } + + sendMessage(subject, msg, files); + +} + +void CreateBlogMsg::sendMessage(std::wstring subject, std::wstring msg, std::list &files) +{ + std::cerr << "CreateBlogMsg::sendMessage()" << std::endl; + + QString name = ui.subjectEdit->text(); + + if(name.isEmpty()) + { /* error message */ + int ret = QMessageBox::warning(this, tr("RetroShare"), + tr("Please add a Subject"), + QMessageBox::Ok, QMessageBox::Ok); + + return; //Don't add a empty Subject!! + } + else + + /* rsChannels */ + if (rsBlogs) + { + BlogMsgInfo msgInfo; + + msgInfo.blogId = mBlogId; + msgInfo.msgId = ""; + + msgInfo.subject = subject; + msgInfo.msg = msg; + msgInfo.files = files; + msgInfo.msgIdReply = "nothing"; + rsBlogs->BlogMessageSend(msgInfo); + } + + close(); + return; + +} + +void CreateBlogMsg::fontSizeIncrease() +{ + if ( !( ui.msgEdit->textCursor().blockFormat().hasProperty( TextFormat::HtmlHeading ) && + ui.msgEdit->textCursor().blockFormat().intProperty( TextFormat::HtmlHeading ) ) ) { + QTextCharFormat format; + int idx = ui.msgEdit->currentCharFormat().intProperty( QTextFormat::FontSizeAdjustment ); + if ( idx < 3 ) { + format.setProperty( QTextFormat::FontSizeAdjustment, QVariant( ++idx ) ); + ui.msgEdit->textCursor().mergeCharFormat( format ); + } + } + ui.msgEdit->setFocus( Qt::OtherFocusReason ); +} + +void CreateBlogMsg::fontSizeDecrease() +{ + if ( !( ui.msgEdit->textCursor().blockFormat().hasProperty( TextFormat::HtmlHeading ) && + ui.msgEdit->textCursor().blockFormat().intProperty( TextFormat::HtmlHeading ) ) ) { + QTextCharFormat format; + int idx = ui.msgEdit->currentCharFormat().intProperty( QTextFormat::FontSizeAdjustment ); + if ( idx > -1 ) { + format.setProperty( QTextFormat::FontSizeAdjustment, QVariant( --idx ) ); + ui.msgEdit->textCursor().mergeCharFormat( format ); + } + } + ui.msgEdit->setFocus( Qt::OtherFocusReason ); +} + +void CreateBlogMsg::blockQuote() +{ + QTextBlockFormat blockFormat = ui.msgEdit->textCursor().blockFormat(); + QTextBlockFormat f; + + if ( blockFormat.hasProperty( TextFormat::IsBlockQuote ) && + blockFormat.boolProperty( TextFormat::IsBlockQuote ) ) { + f.setProperty( TextFormat::IsBlockQuote, QVariant( false ) ); + f.setLeftMargin( 0 ); + f.setRightMargin( 0 ); + } else { + f.setProperty( TextFormat::IsBlockQuote, QVariant( true ) ); + f.setLeftMargin( 40 ); + f.setRightMargin( 40 ); + } + ui.msgEdit->textCursor().mergeBlockFormat( f ); +} + +void CreateBlogMsg::toggleCode() +{ + static QString preFontFamily; + + QTextCharFormat charFormat = ui.msgEdit->currentCharFormat(); + QTextCharFormat f; + + if ( charFormat.hasProperty( TextFormat::HasCodeStyle ) && + charFormat.boolProperty( TextFormat::HasCodeStyle ) ) { + f.setProperty( TextFormat::HasCodeStyle, QVariant( false ) ); + f.setBackground( defaultCharFormat.background() ); + f.setFontFamily( preFontFamily ); + ui.msgEdit->textCursor().mergeCharFormat( f ); + + } else { + preFontFamily = ui.msgEdit->fontFamily(); + f.setProperty( TextFormat::HasCodeStyle, QVariant( true ) ); + f.setBackground( codeBackground ); + f.setFontFamily( "Dejavu Sans Mono" ); + ui.msgEdit->textCursor().mergeCharFormat( f ); + } + ui.msgEdit->setFocus( Qt::OtherFocusReason ); +} + +void CreateBlogMsg::addPostSplitter() +{ + QTextBlockFormat f = ui.msgEdit->textCursor().blockFormat(); + QTextBlockFormat f1 = f; + + f.setProperty( TextFormat::IsHtmlTagSign, true ); + f.setProperty( QTextFormat::BlockTrailingHorizontalRulerWidth, + QTextLength( QTextLength::PercentageLength, 80 ) ); + if ( ui.msgEdit->textCursor().block().text().isEmpty() ) { + ui.msgEdit->textCursor().mergeBlockFormat( f ); + } else { + ui.msgEdit->textCursor().insertBlock( f ); + } + ui.msgEdit->textCursor().insertBlock( f1 ); +} + +void CreateBlogMsg::setStartupText() +{ + QString string = "

HTML Previewer

" + "

This example shows you how to use QWebView to" + " preview HTML data written in a QPlainTextEdit.

" + " "; + //webView->setHtml(string); +} + +void CreateBlogMsg::updateTextEdit() +{ + //QWebFrame *mainFrame = webView->page()->mainFrame(); + QString frameText = ui.msgEdit->toHtml(); + ui.plainTextEdit->setPlainText(frameText); + //QString text = plainTextEdit->toPlainText(); +} + +void CreateBlogMsg::textBold() +{ + QTextCharFormat fmt; + fmt.setFontWeight(actionTextBold->isChecked() ? QFont::Bold : QFont::Normal); + mergeFormatOnWordOrSelection(fmt); +} + +void CreateBlogMsg::textUnderline() +{ + QTextCharFormat fmt; + fmt.setFontUnderline(actionTextUnderline->isChecked()); + mergeFormatOnWordOrSelection(fmt); +} + +void CreateBlogMsg::textItalic() +{ + QTextCharFormat fmt; + fmt.setFontItalic(actionTextItalic->isChecked()); + mergeFormatOnWordOrSelection(fmt); +} + + +void CreateBlogMsg::textAlign(QAction *a) +{ + if (a == actionAlignLeft) + ui.msgEdit->setAlignment(Qt::AlignLeft | Qt::AlignAbsolute); + else if (a == actionAlignCenter) + ui.msgEdit->setAlignment(Qt::AlignHCenter | Qt::AlignAbsolute); + else if (a == actionAlignRight) + ui.msgEdit->setAlignment(Qt::AlignRight | Qt::AlignAbsolute); + else if (a == actionAlignJustify) + ui.msgEdit->setAlignment(Qt::AlignJustify | Qt::AlignAbsolute); + +} + +void CreateBlogMsg::alignmentChanged(Qt::Alignment a) +{ + if (a & Qt::AlignLeft) { + actionAlignLeft->setChecked(true); + } else if (a & Qt::AlignHCenter) { + actionAlignCenter->setChecked(true); + } else if (a & Qt::AlignRight) { + actionAlignRight->setChecked(true); + } else if (a & Qt::AlignJustify) { + actionAlignJustify->setChecked(true); + } +} + +void CreateBlogMsg::textFamily(const QString &f) +{ + QTextCharFormat fmt; + fmt.setFontFamily(f); + mergeFormatOnWordOrSelection(fmt); +} + +void CreateBlogMsg::textSize(const QString &p) +{ + qreal pointSize = p.toFloat(); + if (p.toFloat() > 0) { + QTextCharFormat fmt; + fmt.setFontPointSize(pointSize); + mergeFormatOnWordOrSelection(fmt); + } +} + +void CreateBlogMsg::changeFormatType(int styleIndex ) +{ + ui.msgEdit->setFocus( Qt::OtherFocusReason ); + + QTextCursor cursor = ui.msgEdit->textCursor(); + //QTextBlockFormat bformat = cursor.blockFormat(); + QTextBlockFormat bformat; + QTextCharFormat cformat; + + switch (styleIndex) { + default: + case 0: + bformat.setProperty( TextFormat::HtmlHeading, QVariant( 0 ) ); + cformat.setFontWeight( QFont::Normal ); + cformat.setProperty( QTextFormat::FontSizeAdjustment, QVariant( 0 ) ); + break; + case 1: + bformat.setProperty( TextFormat::HtmlHeading, QVariant( 1 ) ); + cformat.setFontWeight( QFont::Bold ); + cformat.setProperty( QTextFormat::FontSizeAdjustment, QVariant( 3 ) ); + break; + case 2: + bformat.setProperty( TextFormat::HtmlHeading, QVariant( 2 ) ); + cformat.setFontWeight( QFont::Bold ); + cformat.setProperty( QTextFormat::FontSizeAdjustment, QVariant( 2 ) ); + break; + case 3: + bformat.setProperty( TextFormat::HtmlHeading, QVariant( 3 ) ); + cformat.setFontWeight( QFont::Bold ); + cformat.setProperty( QTextFormat::FontSizeAdjustment, QVariant( 1 ) ); + break; + case 4: + bformat.setProperty( TextFormat::HtmlHeading, QVariant( 4 ) ); + cformat.setFontWeight( QFont::Bold ); + cformat.setProperty( QTextFormat::FontSizeAdjustment, QVariant( 0 ) ); + break; + case 5: + bformat.setProperty( TextFormat::HtmlHeading, QVariant( 5 ) ); + cformat.setFontWeight( QFont::Bold ); + cformat.setProperty( QTextFormat::FontSizeAdjustment, QVariant( -1 ) ); + break; + case 6: + bformat.setProperty( TextFormat::HtmlHeading, QVariant( 6 ) ); + cformat.setFontWeight( QFont::Bold ); + cformat.setProperty( QTextFormat::FontSizeAdjustment, QVariant( -2 ) ); + break; + } + //cformat.clearProperty( TextFormat::HasCodeStyle ); + + cursor.beginEditBlock(); + cursor.mergeBlockFormat( bformat ); + cursor.select( QTextCursor::BlockUnderCursor ); + cursor.mergeCharFormat( cformat ); + cursor.endEditBlock(); +} + + +void CreateBlogMsg::textColor() +{ + QColor col = QColorDialog::getColor(ui.msgEdit->textColor(), this); + if (!col.isValid()) + return; + QTextCharFormat fmt; + fmt.setForeground(col); + mergeFormatOnWordOrSelection(fmt); + colorChanged(col); +} + +void CreateBlogMsg::fontChanged(const QFont &f) +{ + comboFont->setCurrentIndex(comboFont->findText(QFontInfo(f).family())); + comboSize->setCurrentIndex(comboSize->findText(QString::number(f.pointSize()))); + actionTextBold->setChecked(f.bold()); + actionTextItalic->setChecked(f.italic()); + actionTextUnderline->setChecked(f.underline()); +} + +void CreateBlogMsg::colorChanged(const QColor &c) +{ + QPixmap pix(16, 16); + pix.fill(c); + //ui.colorbtn->setIcon(pix); + actionTextColor->setIcon(pix); +} + +void CreateBlogMsg::mergeFormatOnWordOrSelection(const QTextCharFormat &format) +{ + QTextCursor cursor = ui.msgEdit->textCursor(); + if (!cursor.hasSelection()) + cursor.select(QTextCursor::WordUnderCursor); + cursor.mergeCharFormat(format); + ui.msgEdit->mergeCurrentCharFormat(format); +} + +void CreateBlogMsg::currentCharFormatChanged(const QTextCharFormat &format) +{ + fontChanged(format.font()); + colorChanged(format.foreground().color()); +} + +void CreateBlogMsg::cursorPositionChanged() +{ + alignmentChanged(ui.msgEdit->alignment()); +} + +void CreateBlogMsg::clipboardDataChanged() +{ +#ifndef QT_NO_CLIPBOARD + actionPaste->setEnabled(!QApplication::clipboard()->text().isEmpty()); +#endif +} + + +void CreateBlogMsg::addOrderedList() +{ + ui.msgEdit->textCursor().createList( QTextListFormat::ListDecimal ); + +} + +void CreateBlogMsg::addUnorderedList() +{ + ui.msgEdit->textCursor().createList( QTextListFormat::ListDisc ); +} + +void CreateBlogMsg::setupFileActions() +{ + QMenu *menu = new QMenu(tr("&File"), this); + menuBar()->addMenu(menu); + + QAction *a; + + a = new QAction(QIcon(":/images/textedit/filenew.png"), tr("&New"), this); + a->setShortcut(QKeySequence::New); + connect(a, SIGNAL(triggered()), this, SLOT(fileNew())); + menu->addAction(a); + + a = new QAction(QIcon(":/images/textedit/fileopen.png"), tr("&Open..."), this); + a->setShortcut(QKeySequence::Open); + connect(a, SIGNAL(triggered()), this, SLOT(fileOpen())); + menu->addAction(a); + + menu->addSeparator(); + + actionSave = a = new QAction(QIcon(":/images/textedit/filesave.png"), tr("&Save"), this); + a->setShortcut(QKeySequence::Save); + connect(a, SIGNAL(triggered()), this, SLOT(fileSave())); + a->setEnabled(false); + menu->addAction(a); + + a = new QAction(tr("Save &As..."), this); + connect(a, SIGNAL(triggered()), this, SLOT(fileSaveAs())); + menu->addAction(a); + menu->addSeparator(); + + a = new QAction(QIcon(":/images/textedit/fileprint.png"), tr("&Print..."), this); + a->setShortcut(QKeySequence::Print); + connect(a, SIGNAL(triggered()), this, SLOT(filePrint())); + menu->addAction(a); + + a = new QAction(QIcon(":/images/textedit/fileprint.png"), tr("Print Preview..."), this); + connect(a, SIGNAL(triggered()), this, SLOT(filePrintPreview())); + menu->addAction(a); + + a = new QAction(QIcon(":/images/textedit/exportpdf.png"), tr("&Export PDF..."), this); + a->setShortcut(Qt::CTRL + Qt::Key_D); + connect(a, SIGNAL(triggered()), this, SLOT(filePrintPdf())); + menu->addAction(a); + + menu->addSeparator(); + + a = new QAction(tr("&Quit"), this); + a->setShortcut(Qt::CTRL + Qt::Key_Q); + connect(a, SIGNAL(triggered()), this, SLOT(cancelMsg())); + menu->addAction(a); +} + +void CreateBlogMsg::setupEditActions() +{ + QMenu *menu = new QMenu(tr("&Edit"), this); + menuBar()->addMenu(menu); + + QAction *a; + a = actionUndo = new QAction(QIcon(":/images/textedit/editundo.png"), tr("&Undo"), this); + a->setShortcut(QKeySequence::Undo); + menu->addAction(a); + a = actionRedo = new QAction(QIcon(":/images/textedit/editredo.png"), tr("&Redo"), this); + a->setShortcut(QKeySequence::Redo); + menu->addAction(a); + menu->addSeparator(); + a = actionCut = new QAction(QIcon(":/images/textedit/editcut.png"), tr("Cu&t"), this); + a->setShortcut(QKeySequence::Cut); + menu->addAction(a); + a = actionCopy = new QAction(QIcon(":/images/textedit/editcopy.png"), tr("&Copy"), this); + a->setShortcut(QKeySequence::Copy); + menu->addAction(a); + a = actionPaste = new QAction(QIcon(":/images/textedit/editpaste.png"), tr("&Paste"), this); + a->setShortcut(QKeySequence::Paste); + menu->addAction(a); + actionPaste->setEnabled(!QApplication::clipboard()->text().isEmpty()); +} + +void CreateBlogMsg::setupViewActions() +{ + QMenu *menu = new QMenu(tr("&View"), this); + menuBar()->addMenu(menu); + + QAction *a; + + +} + +void CreateBlogMsg::setupInsertActions() +{ + QMenu *menu = new QMenu(tr("&Insert"), this); + menuBar()->addMenu(menu); + + QAction *a; + + a = new QAction(QIcon(""), tr("&Image"), this); + connect(a, SIGNAL(triggered()), this, SLOT(addImage())); + menu->addAction(a); + +} + +void CreateBlogMsg::setupParagraphActions() +{ + comboStyle = new QComboBox(ui.toolBar_2); + ui.toolBar_2->addWidget(comboStyle); + comboStyle->addItem("Paragraph"); + comboStyle->addItem("Heading 1"); + comboStyle->addItem("Heading 2"); + comboStyle->addItem("Heading 3"); + comboStyle->addItem("Heading 4"); + comboStyle->addItem("Heading 5"); + comboStyle->addItem("Heading 6"); + + connect(comboStyle, SIGNAL(activated(int)), + this, SLOT(changeFormatType(int))); +} + +void CreateBlogMsg::setupTextActions() +{ + + QMenu *menu = new QMenu(tr("F&ormat"), this); + menuBar()->addMenu(menu); + + actionTextBold = new QAction(QIcon(":/images/textedit/textbold.png"),tr("&Bold"), this); + actionTextBold->setShortcut(Qt::CTRL + Qt::Key_B); + //actionTextBold->setPriority(QAction::LowPriority); + QFont bold; + bold.setBold(true); + actionTextBold->setFont(bold); + connect(actionTextBold, SIGNAL(triggered()), this, SLOT(textBold())); + + ui.toolBar_2->addAction(actionTextBold); + menu->addAction(actionTextBold); + actionTextBold->setCheckable(true); + + actionTextItalic = new QAction(QIcon(":/images/textedit/textitalic.png"),tr("&Italic"), this); + //actionTextItalic->setPriority(QAction::LowPriority); + actionTextItalic->setShortcut(Qt::CTRL + Qt::Key_I); + QFont italic; + italic.setItalic(true); + actionTextItalic->setFont(italic); + connect(actionTextItalic, SIGNAL(triggered()), this, SLOT(textItalic())); + + ui.toolBar_2->addAction(actionTextItalic); + menu->addAction(actionTextItalic); + actionTextItalic->setCheckable(true); + + actionTextUnderline = new QAction(QIcon(":/images/textedit/textunder.png"),tr("&Underline"), this); + actionTextUnderline->setShortcut(Qt::CTRL + Qt::Key_U); + //actionTextUnderline->setPriority(QAction::LowPriority); + QFont underline; + underline.setUnderline(true); + actionTextUnderline->setFont(underline); + connect(actionTextUnderline, SIGNAL(triggered()), this, SLOT(textUnderline())); + + ui.toolBar_2->addAction(actionTextUnderline); + menu->addAction(actionTextUnderline); + actionTextUnderline->setCheckable(true); + + menu->addSeparator(); + + QActionGroup *grp = new QActionGroup(this); + connect(grp, SIGNAL(triggered(QAction*)), this, SLOT(textAlign(QAction*))); + + // Make sure the alignLeft is always left of the alignRight + if (QApplication::isLeftToRight()) { + actionAlignLeft = new QAction(QIcon(":/images/textedit/textleft.png"),tr("&Left"), grp); + actionAlignCenter = new QAction(QIcon(":/images/textedit/textcenter.png"), tr("C&enter"), grp); + actionAlignRight = new QAction(QIcon(":/images/textedit/textright.png"), tr("&Right"), grp); + } else { + actionAlignRight = new QAction(QIcon(":/images/textedit/textright.png"), tr("&Right"), grp); + actionAlignCenter = new QAction(QIcon(":/images/textedit/textcenter.png"), tr("C&enter"), grp); + actionAlignLeft = new QAction(QIcon(":/images/textedit/textleft.png"), tr("&Left"), grp); + } + actionAlignJustify = new QAction(QIcon(":/images/textedit/textjustify.png"), tr("&Justify"), grp); + + actionAlignLeft->setShortcut(Qt::CTRL + Qt::Key_L); + actionAlignLeft->setCheckable(true); + //actionAlignLeft->setPriority(QAction::LowPriority); + actionAlignCenter->setShortcut(Qt::CTRL + Qt::Key_E); + actionAlignCenter->setCheckable(true); + //actionAlignCenter->setPriority(QAction::LowPriority); + actionAlignRight->setShortcut(Qt::CTRL + Qt::Key_R); + actionAlignRight->setCheckable(true); + //actionAlignRight->setPriority(QAction::LowPriority); + actionAlignJustify->setShortcut(Qt::CTRL + Qt::Key_J); + actionAlignJustify->setCheckable(true); + //actionAlignJustify->setPriority(QAction::LowPriority); + + ui.toolBar_2->addActions(grp->actions()); + menu->addActions(grp->actions()); + + menu->addSeparator(); + + QPixmap pix(16, 16); + pix.fill(Qt::black); + actionTextColor = new QAction(pix, tr("&Text Color..."), this); + connect(actionTextColor, SIGNAL(triggered()), this, SLOT(textColor())); + + ui.toolBar_2->addAction(actionTextColor); + menu->addAction(actionTextColor); + + menu->addAction(ui.actionOrderedlist); + menu->addAction(ui.actionUnorderedlist); + menu->addAction(ui.actionBlockquoute); + + + /*comboStyle = new QComboBox(ui.toolBar_2); + ui.toolBar_2->addWidget(comboStyle); + comboStyle->addItem("Paragraph"); + comboStyle->addItem("Heading 1"); + comboStyle->addItem("Heading 2"); + comboStyle->addItem("Heading 3"); + comboStyle->addItem("Heading 4"); + comboStyle->addItem("Heading 5"); + comboStyle->addItem("Heading 6"); + + connect(comboStyle, SIGNAL(activated(int)), + this, SLOT(changeFormatType(int)));*/ + + comboFont = new QFontComboBox(ui.toolBar_2); + ui.toolBar_2->addWidget(comboFont); + connect(comboFont, SIGNAL(activated(QString)), + this, SLOT(textFamily(QString))); + + comboSize = new QComboBox(ui.toolBar_2); + comboSize->setObjectName("comboSize"); + ui.toolBar_2->addWidget(comboSize); + comboSize->setEditable(true); + + QFontDatabase db; + foreach(int size, db.standardSizes()) + comboSize->addItem(QString::number(size)); + + connect(comboSize, SIGNAL(activated(QString)), + this, SLOT(textSize(QString))); + comboSize->setCurrentIndex(comboSize->findText(QString::number(QApplication::font() + .pointSize()))); +} + +bool CreateBlogMsg::load(const QString &f) +{ + if (!QFile::exists(f)) + return false; + QFile file(f); + if (!file.open(QFile::ReadOnly)) + return false; + + QByteArray data = file.readAll(); + QTextCodec *codec = Qt::codecForHtml(data); + QString str = codec->toUnicode(data); + if (Qt::mightBeRichText(str)) { + ui.msgEdit->setHtml(str); + } else { + str = QString::fromLocal8Bit(data); + ui.msgEdit->setPlainText(str); + } + + setCurrentFileName(f); + return true; +} + +bool CreateBlogMsg::maybeSave() +{ + if (!ui.msgEdit->document()->isModified()) + return true; + if (fileName.startsWith(QLatin1String(":/"))) + return true; + QMessageBox::StandardButton ret; + ret = QMessageBox::warning(this, tr("Application"), + tr("The document has been modified.\n" + "Do you want to save your changes?"), + QMessageBox::Save | QMessageBox::Discard + | QMessageBox::Cancel); + if (ret == QMessageBox::Save) + return fileSave(); + else if (ret == QMessageBox::Cancel) + return false; + return true; +} + +void CreateBlogMsg::fileNew() +{ + if (maybeSave()) { + ui.msgEdit->clear(); + setCurrentFileName(QString()); + } +} + +void CreateBlogMsg::fileOpen() +{ + QString fn = QFileDialog::getOpenFileName(this, tr("Open File..."), + QString(), tr("HTML-Files (*.htm *.html);;All Files (*)")); + if (!fn.isEmpty()) + load(fn); +} + +bool CreateBlogMsg::fileSave() +{ + if (fileName.isEmpty()) + return fileSaveAs(); + + QTextDocumentWriter writer(fileName); + bool success = writer.write(ui.msgEdit->document()); + if (success) + ui.msgEdit->document()->setModified(false); + return success; +} + +bool CreateBlogMsg::fileSaveAs() +{ + QString fn = QFileDialog::getSaveFileName(this, tr("Save as..."), + QString(), tr("ODF files (*.odt);;HTML-Files (*.htm *.html);;All Files (*)")); + if (fn.isEmpty()) + return false; + if (! (fn.endsWith(".odt", Qt::CaseInsensitive) || fn.endsWith(".htm", Qt::CaseInsensitive) || fn.endsWith(".html", Qt::CaseInsensitive)) ) + fn += ".odt"; // default + setCurrentFileName(fn); + return fileSave(); +} + +void CreateBlogMsg::filePrint() +{ +#ifndef QT_NO_PRINTER + QPrinter printer(QPrinter::HighResolution); + QPrintDialog *dlg = new QPrintDialog(&printer, this); + if (ui.msgEdit->textCursor().hasSelection()) + dlg->addEnabledOption(QAbstractPrintDialog::PrintSelection); + dlg->setWindowTitle(tr("Print Document")); + if (dlg->exec() == QDialog::Accepted) { + ui.msgEdit->print(&printer); + } + delete dlg; +#endif +} + +void CreateBlogMsg::filePrintPreview() +{ +#ifndef QT_NO_PRINTER + QPrinter printer(QPrinter::HighResolution); + QPrintPreviewDialog preview(&printer, this); + connect(&preview, SIGNAL(paintRequested(QPrinter*)), SLOT(printPreview(QPrinter*))); + preview.exec(); +#endif +} + +void CreateBlogMsg::printPreview(QPrinter *printer) +{ +#ifdef QT_NO_PRINTER + Q_UNUSED(printer); +#else + ui.msgEdit->print(printer); +#endif +} + + +void CreateBlogMsg::filePrintPdf() +{ +#ifndef QT_NO_PRINTER +//! [0] + QString fileName = QFileDialog::getSaveFileName(this, "Export PDF", + QString(), "*.pdf"); + if (!fileName.isEmpty()) { + if (QFileInfo(fileName).suffix().isEmpty()) + fileName.append(".pdf"); + QPrinter printer(QPrinter::HighResolution); + printer.setOutputFormat(QPrinter::PdfFormat); + printer.setOutputFileName(fileName); + ui.msgEdit->document()->print(&printer); + } +//! [0] +#endif +} + +void CreateBlogMsg::setCurrentFileName(const QString &fileName) +{ + this->fileName = fileName; + ui.msgEdit->document()->setModified(false); + + QString shownName; + if (fileName.isEmpty()) + shownName = "untitled.txt"; + else + shownName = QFileInfo(fileName).fileName(); + + //setWindowTitle(tr("%1[*] - %2").arg(shownName).arg(tr("Rich Text"))); + setWindowModified(false); +} + +void CreateBlogMsg::addImage() +{ + + QString fileimg = QFileDialog::getOpenFileName( this, tr( "Choose Image" ), + QString(setter.value("LastDir").toString()) ,tr("Image Files supported (*.png *.jpeg *.jpg *.gif)")); + + if ( fileimg.isEmpty() ) { + return; + } + + QImage base(fileimg); + + QString pathimage = fileimg.left(fileimg.lastIndexOf("/"))+"/"; + setter.setValue("LastDir",pathimage); + + Create_New_Image_Tag(fileimg); +} + +void CreateBlogMsg::Create_New_Image_Tag( const QString urlremoteorlocal ) +{ + /*if (image_extension(urlremoteorlocal)) {*/ + QString subtext = QString("

").arg(urlremoteorlocal); + ///////////subtext.append("

Description on image.

"); + QTextDocumentFragment fragment = QTextDocumentFragment::fromHtml(subtext); + ui.msgEdit->textCursor().insertFragment(fragment); + //emit statusMessage(QString("Image new :").arg(urlremoteorlocal)); + //} +} \ No newline at end of file diff --git a/retroshare-gui/src/gui/unfinished/blogs/CreateBlogMsg.h b/retroshare-gui/src/gui/unfinished/blogs/CreateBlogMsg.h new file mode 100644 index 000000000..f33fd567e --- /dev/null +++ b/retroshare-gui/src/gui/unfinished/blogs/CreateBlogMsg.h @@ -0,0 +1,176 @@ +/**************************************************************** + * RetroShare is distributed under the following license: + * + * Copyright (C) 2008 Robert Fernie + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + +#ifndef _CREATEBLOGMSG_H +#define _CREATEBLOGMSG_H + +#include +#include +#include +#include +#include + +#include "ui_CreateBlogMsg.h" +#include + +class SubFileItem; +class FileInfo; + +QT_FORWARD_DECLARE_CLASS(QAction) +QT_FORWARD_DECLARE_CLASS(QComboBox) +QT_FORWARD_DECLARE_CLASS(QFontComboBox) +QT_FORWARD_DECLARE_CLASS(QTextEdit) +QT_FORWARD_DECLARE_CLASS(QTextCharFormat) +QT_FORWARD_DECLARE_CLASS(QMenu) + +class CreateBlogMsg : public QMainWindow +{ + Q_OBJECT + +public: + /** Default Constructor */ + CreateBlogMsg(std::string cId, QWidget *parent = 0, Qt::WFlags flags = 0); + /** Default Destructor */ + + void addAttachment(std::string path); + void addAttachment(std::string hash, std::string fname, uint64_t size, + bool local, std::string srcId); + + void newBlogMsg(); + + QPixmap picture; + QSettings setter; + + void Create_New_Image_Tag( const QString urlremoteorlocal ); + +protected: +virtual void dragEnterEvent(QDragEnterEvent *event); +virtual void dropEvent(QDropEvent *event); + +private slots: + void addExtraFile(); + void checkAttachmentReady(); + + void cancelMsg(); + void sendMsg(); + void addImage(); + + void fontSizeIncrease(); + void fontSizeDecrease(); + void blockQuote(); + void toggleCode(); + void addPostSplitter(); + + void setStartupText(); + void updateTextEdit(); + + void fileNew(); + void fileOpen(); + bool fileSave(); + bool fileSaveAs(); + void filePrint(); + void filePrintPreview(); + void filePrintPdf(); + void printPreview(QPrinter *); + + void textBold(); + void textUnderline(); + void textItalic(); + void textFamily(const QString &f); + void textSize(const QString &p); + void changeFormatType(int styleIndex ); + + + void textColor(); + void textAlign(QAction *a); + + void addOrderedList(); + void addUnorderedList(); + + void currentCharFormatChanged(const QTextCharFormat &format); + void cursorPositionChanged(); + + void clipboardDataChanged(); + + +private: + void setupFileActions(); + void setupEditActions(); + void setupViewActions(); + void setupInsertActions(); + void setupParagraphActions(); + void setupTextActions(); + + void setCurrentFileName(const QString &fileName); + bool load(const QString &f); + bool maybeSave(); + + void mergeFormatOnWordOrSelection(const QTextCharFormat &format); + + void fontChanged(const QFont &f); + void colorChanged(const QColor &c); + void alignmentChanged(Qt::Alignment a); + + void parseRsFileListAttachments(std::string attachList); + + void sendMessage(std::wstring subject, std::wstring msg, std::list &files); + + std::string mBlogId; + + std::list mAttachments; + + bool mCheckAttachment; + + QAction *actionSave, + *actionTextBold, + *actionTextUnderline, + *actionTextItalic, + *actionTextColor, + *actionAlignLeft, + *actionAlignCenter, + *actionAlignRight, + *actionAlignJustify, + *actionUndo, + *actionRedo, + *actionCut, + *actionCopy, + *actionPaste; + + QComboBox *comboStyle; + QFontComboBox *comboFont; + QComboBox *comboSize; + + QString fileName; + + QColor codeBackground; + QTextCharFormat defaultCharFormat; + QTextBlockFormat defaultBlockFormat; + QTextCharFormat lastCharFormat; + QTextBlockFormat lastBlockFormat; + + /** Qt Designer generated object */ + Ui::CreateBlogMsg ui; +}; + + + +#endif + diff --git a/retroshare-gui/src/gui/unfinished/blogs/CreateBlogMsg.ui b/retroshare-gui/src/gui/unfinished/blogs/CreateBlogMsg.ui new file mode 100644 index 000000000..2aab28f5e --- /dev/null +++ b/retroshare-gui/src/gui/unfinished/blogs/CreateBlogMsg.ui @@ -0,0 +1,483 @@ + + + CreateBlogMsg + + + + 0 + 0 + 666 + 515 + + + + New Blog Post + + + + :/images/rstray3.png:/images/rstray3.png + + + QToolBar#toolBar{background-image: url(:/images/connect/connectFriendBanner.png); +} + +QToolButton { + color: white; +} + +QToolBar#toolBar_2{ +background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, +stop:0 #FEFEFE, stop:1 #E8E8E8); + +border: 1px solid #CCCCCC;} + + + + + 0 + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + + + QTabWidget::South + + + 0 + + + + Blog Post + + + + + + + + + 75 + true + + + + Blog Post to: + + + + + + + true + + + true + + + + + + + + + 0 + + + + Visual Editor + + + + + + Blog Message + + + + + + + + + 75 + true + + + + Subject : + + + + + + + + + + + + + + + + + + + Html Editor + + + + + + + + + + + + + + + :/images/attachment.png:/images/attachment.png + + + Attachments + + + + 0 + + + 0 + + + + + 0 + + + 6 + + + 6 + + + + + + + + :/images/attachment.png + + + + + + + + 16777215 + 26 + + + + + 75 + true + + + + Attachments + + + + + + + Qt::Horizontal + + + + 334 + 26 + + + + + + + + + 0 + 0 + + + + + 34 + 34 + + + + + + + + :/images/add-share24.png:/images/add-share24.png + + + + 24 + 24 + + + + + + + + + + Qt::ScrollBarAlwaysOn + + + true + + + + + 0 + 0 + 639 + 341 + + + + + + + + + + Qt::Vertical + + + + 438 + 137 + + + + + + + + + + + + + + + + + + + + + 0 + 0 + 666 + 21 + + + + + + + + 0 + 32 + + + + + 9 + + + + toolBar + + + TopToolBarArea + + + false + + + + + + + + toolBar_2 + + + TopToolBarArea + + + true + + + + + + true + + + + :/images/textedit/hi22-action-format-text-blockquote.png:/images/textedit/hi22-action-format-text-blockquote.png + + + blockquoute + + + + + + :/images/textedit/format_font_size_more.png:/images/textedit/format_font_size_more.png + + + Increase font Size + + + + + + :/images/textedit/format_font_size_less.png:/images/textedit/format_font_size_less.png + + + Decrease font size + + + + + + :/images/textedit/textbold.png:/images/textedit/textbold.png + + + Bold + + + + + + :/images/textedit/textunder.png:/images/textedit/textunder.png + + + Underline + + + + + + :/images/textedit/textitalic.png:/images/textedit/textitalic.png + + + Italic + + + + + Publish + + + + + New + + + + + + :/images/textedit/hi22-action-format-text-code.png:/images/textedit/hi22-action-format-text-code.png + + + Code + + + + + + :/images/textedit/hi22-action-insert-more-mark.png:/images/textedit/hi22-action-insert-more-mark.png + + + splitPost + + + + + + :/images/textedit/format-list-ordered.png:/images/textedit/format-list-ordered.png + + + Ordered List + + + + + + :/images/textedit/format-list-unordered.png:/images/textedit/format-list-unordered.png + + + Unordered List + + + + + true + + + + :/images/textedit/editcut.png:/images/textedit/editcut.png + + + Clipboard + + + + + + :/images/textedit/editundo.png:/images/textedit/editundo.png + + + Undo + + + + + + + + + + + + + + + +