diff --git a/retroshare-gui/src/RetroShare.pro b/retroshare-gui/src/RetroShare.pro index 8687e8ffe..8afc16798 100644 --- a/retroshare-gui/src/RetroShare.pro +++ b/retroshare-gui/src/RetroShare.pro @@ -1,7 +1,9 @@ CONFIG += qt gui uic qrc resources uitools idle bitdht -CONFIG += photoshare wikipoos +CONFIG += photoshare +CONFIG += wikipoos CONFIG += thewire CONFIG += identities +CONFIG += forumsv2 CONFIG += unfinished QT += network xml script @@ -912,16 +914,38 @@ thewire { identities { - HEADERS += gui/Identity/IdDialog.h \ + HEADERS += util/TokenQueue.h \ + gui/Identity/IdDialog.h \ gui/Identity/IdEditDialog.h \ - util/TokenQueue.h \ FORMS += gui/Identity/IdDialog.ui \ gui/Identity/IdEditDialog.ui \ - SOURCES += gui/Identity/IdDialog.cpp \ + SOURCES += util/TokenQueue.cpp \ + gui/Identity/IdDialog.cpp \ gui/Identity/IdEditDialog.cpp \ - util/TokenQueue.cpp \ } + +forumsv2 { + + HEADERS += gui/ForumsV2Dialog.h \ + gui/forumsv2/ForumV2Details.h \ + gui/forumsv2/EditForumV2Details.h \ + gui/forumsv2/CreateForumV2.h \ + gui/forumsv2/CreateForumV2Msg.h \ + + FORMS += gui/ForumsV2Dialog.ui \ + gui/forumsv2/ForumV2Details.ui \ + gui/forumsv2/EditForumV2Details.ui \ + gui/forumsv2/CreateForumV2.ui \ + gui/forumsv2/CreateForumV2Msg.ui \ + + SOURCES += gui/ForumsV2Dialog.cpp \ + gui/forumsv2/ForumV2Details.cpp \ + gui/forumsv2/EditForumV2Details.cpp \ + gui/forumsv2/CreateForumV2.cpp \ + gui/forumsv2/CreateForumV2Msg.cpp \ + +} diff --git a/retroshare-gui/src/gui/ForumsV2Dialog.cpp b/retroshare-gui/src/gui/ForumsV2Dialog.cpp new file mode 100644 index 000000000..54c20d20d --- /dev/null +++ b/retroshare-gui/src/gui/ForumsV2Dialog.cpp @@ -0,0 +1,2295 @@ +/**************************************************************** + * 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 "ForumsV2Dialog.h" + +#include "forumsv2/CreateForumV2.h" +#include "forumsv2/CreateForumV2Msg.h" +#include "forumsv2/ForumV2Details.h" +#include "forumsv2/EditForumV2Details.h" + +#include "msgs/MessageComposer.h" +#include "settings/rsharesettings.h" +#include "common/Emoticons.h" +#include "common/RSItemDelegate.h" +#include "common/PopularityDefs.h" +#include "RetroShareLink.h" +#include "channels/ShareKey.h" + +#include +#include + +#include + +//#define DEBUG_FORUMS + +/* Images for context menu icons */ +#define IMAGE_MESSAGE ":/images/folder-draft.png" +#define IMAGE_MESSAGEREPLY ":/images/mail_reply.png" +#define IMAGE_MESSAGEREMOVE ":/images/mail_delete.png" +#define IMAGE_DOWNLOAD ":/images/start.png" +#define IMAGE_DOWNLOADALL ":/images/startall.png" + +/* Images for TreeWidget */ +#define IMAGE_FOLDER ":/images/folder16.png" +#define IMAGE_FOLDERGREEN ":/images/folder_green.png" +#define IMAGE_FOLDERRED ":/images/folder_red.png" +#define IMAGE_FOLDERYELLOW ":/images/folder_yellow.png" +#define IMAGE_FORUM ":/images/konversation16.png" +#define IMAGE_SUBSCRIBE ":/images/edit_add24.png" +#define IMAGE_UNSUBSCRIBE ":/images/cancel.png" +#define IMAGE_INFO ":/images/info16.png" +#define IMAGE_NEWFORUM ":/images/new_forum16.png" +#define IMAGE_FORUMAUTHD ":/images/konv_message2.png" +#define IMAGE_COPYLINK ":/images/copyrslink.png" + +#define VIEW_LAST_POST 0 +#define VIEW_THREADED 1 +#define VIEW_FLAT 2 + +/* Thread constants */ +#define COLUMN_THREAD_COUNT 6 +#define COLUMN_THREAD_TITLE 0 +#define COLUMN_THREAD_READ 1 +#define COLUMN_THREAD_DATE 2 +#define COLUMN_THREAD_AUTHOR 3 +#define COLUMN_THREAD_SIGNED 4 +#define COLUMN_THREAD_CONTENT 5 + +#define COLUMN_THREAD_DATA 0 // column for storing the userdata like msgid and parentid + +#define ROLE_THREAD_MSGID Qt::UserRole +#define ROLE_THREAD_STATUS Qt::UserRole + 1 +#define ROLE_THREAD_MISSING Qt::UserRole + 2 +// no need to copy, don't count in ROLE_THREAD_COUNT +#define ROLE_THREAD_READCHILDREN Qt::UserRole + 3 +#define ROLE_THREAD_UNREADCHILDREN Qt::UserRole + 4 + +#define ROLE_THREAD_COUNT 3 + +#define IS_UNREAD(status) ((status & RSGXS_MSG_STATUS_READ) == 0 || (status & RSGXS_MSG_STATUS_UNREAD_BY_USER)) +#define IS_FORUM_ADMIN(subscribeFlags) (subscribeFlags & RS_DISTRIB_ADMIN) +#define IS_FORUM_SUBSCRIBED(subscribeFlags) (subscribeFlags & (RS_DISTRIB_ADMIN | RS_DISTRIB_SUBSCRIBED)) + + + + +static int FilterColumnFromComboBox(int nIndex) +{ + switch (nIndex) { + case 0: + return COLUMN_THREAD_DATE; + case 1: + return COLUMN_THREAD_TITLE; + case 2: + return COLUMN_THREAD_AUTHOR; + case 3: + return COLUMN_THREAD_CONTENT; + } + + return COLUMN_THREAD_TITLE; +} + +static int FilterColumnToComboBox(int nIndex) +{ + switch (nIndex) { + case COLUMN_THREAD_DATE: + return 0; + case COLUMN_THREAD_TITLE: + return 1; + case COLUMN_THREAD_AUTHOR: + return 2; + case COLUMN_THREAD_CONTENT: + return 3; + } + + return FilterColumnToComboBox(COLUMN_THREAD_TITLE); +} + +/** Constructor */ +ForumsV2Dialog::ForumsV2Dialog(QWidget *parent) +: RsAutoUpdatePage(1000,parent) +{ + /* Invoke the Qt Designer generated object setup routine */ + ui.setupUi(this); + + m_bProcessSettings = false; + subscribeFlags = 0; + + connect( ui.forumTreeWidget, SIGNAL( treeCustomContextMenuRequested( QPoint ) ), this, SLOT( forumListCustomPopupMenu( QPoint ) ) ); + connect( ui.threadTreeWidget, SIGNAL( customContextMenuRequested( QPoint ) ), this, SLOT( threadListCustomPopupMenu( QPoint ) ) ); + + connect(ui.newForumButton, SIGNAL(clicked()), this, SLOT(newforum())); + connect(ui.newmessageButton, SIGNAL(clicked()), this, SLOT(createmessage())); + connect(ui.newthreadButton, SIGNAL(clicked()), this, SLOT(createthread())); + + connect( ui.forumTreeWidget, SIGNAL( treeCurrentItemChanged(QString) ), this, SLOT( changedForum(QString) ) ); + + connect( ui.threadTreeWidget, SIGNAL( itemSelectionChanged() ), this, SLOT( changedThread () ) ); + connect( ui.threadTreeWidget, SIGNAL( itemClicked(QTreeWidgetItem*,int)), this, SLOT( clickedThread (QTreeWidgetItem*,int) ) ); + connect( ui.viewBox, SIGNAL( currentIndexChanged ( int ) ), this, SLOT( changedViewBox () ) ); + + connect(ui.expandButton, SIGNAL(clicked()), this, SLOT(togglethreadview())); + connect(ui.previousButton, SIGNAL(clicked()), this, SLOT(previousMessage())); + connect(ui.nextButton, SIGNAL(clicked()), this, SLOT(nextMessage())); + connect(ui.nextUnreadButton, SIGNAL(clicked()), this, SLOT(nextUnreadMessage())); + + connect(ui.downloadButton, SIGNAL(clicked()), this, SLOT(downloadAllFiles())); + + connect(ui.clearButton, SIGNAL(clicked()), this, SLOT(clearFilter())); + connect(ui.filterPatternLineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(filterRegExpChanged())); + connect(ui.filterColumnComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(filterColumnChanged())); + + /* Set initial size the splitter */ + QList sizes; + sizes << 300 << width(); // Qt calculates the right sizes + //ui.splitter->setSizes(sizes); + + /* Set own item delegate */ + RSItemDelegate *itemDelegate = new RSItemDelegate(this); + itemDelegate->setSpacing(QSize(0, 2)); + ui.threadTreeWidget->setItemDelegate(itemDelegate); + + /* Set header resize modes and initial section sizes */ + QHeaderView * ttheader = ui.threadTreeWidget->header () ; + ttheader->setResizeMode (COLUMN_THREAD_TITLE, QHeaderView::Interactive); + ttheader->resizeSection (COLUMN_THREAD_DATE, 140); + ttheader->resizeSection (COLUMN_THREAD_TITLE, 290); + + ui.threadTreeWidget->sortItems( COLUMN_THREAD_DATE, Qt::DescendingOrder ); + + /* Set text of column "Read" to empty - without this the column has a number as header text */ + QTreeWidgetItem *headerItem = ui.threadTreeWidget->headerItem(); + headerItem->setText(COLUMN_THREAD_READ, ""); + + m_ForumNameFont = QFont("Times", 12, QFont::Bold); + ui.forumName->setFont(m_ForumNameFont); + ui.threadTitle->setFont(m_ForumNameFont); + + /* Initialize group tree */ + ui.forumTreeWidget->initDisplayMenu(ui.displayButton); + + /* create forum tree */ + yourForums = ui.forumTreeWidget->addCategoryItem(tr("Your Forums"), QIcon(IMAGE_FOLDER), true); + subscribedForums = ui.forumTreeWidget->addCategoryItem(tr("Subscribed Forums"), QIcon(IMAGE_FOLDERRED), true); + popularForums = ui.forumTreeWidget->addCategoryItem(tr("Popular Forums"), QIcon(IMAGE_FOLDERGREEN), false); + otherForums = ui.forumTreeWidget->addCategoryItem(tr("Other Forums"), QIcon(IMAGE_FOLDERYELLOW), false); + + lastViewType = -1; + + ui.clearButton->hide(); + + // load settings + processSettings(true); + + /* Set header sizes for the fixed columns and resize modes, must be set after processSettings */ + ttheader->resizeSection (COLUMN_THREAD_READ, 24); + ttheader->setResizeMode (COLUMN_THREAD_READ, QHeaderView::Fixed); + ttheader->hideSection (COLUMN_THREAD_CONTENT); + + ui.progressBar->setTextVisible(true); + ui.progressBar->hide(); + ui.progLayOutTxt->hide(); + ui.progressBarLayOut->setEnabled(false); + + mThreadLoading = false; + + insertThreads(); + + ui.threadTreeWidget->installEventFilter(this); + + /* Hide platform specific features */ +#ifdef Q_WS_WIN + +#endif +} + +ForumsV2Dialog::~ForumsV2Dialog() +{ + // save settings + processSettings(false); +} + +void ForumsV2Dialog::processSettings(bool bLoad) +{ + m_bProcessSettings = true; + + QHeaderView *pHeader = ui.threadTreeWidget->header () ; + + Settings->beginGroup(QString("ForumsV2Dialog")); + + if (bLoad) { + // load settings + + // expandFiles + bool bValue = Settings->value("expandButton", true).toBool(); + ui.expandButton->setChecked(bValue); + togglethreadview_internal(); + + // filterColumn + int nValue = FilterColumnToComboBox(Settings->value("filterColumn", true).toInt()); + ui.filterColumnComboBox->setCurrentIndex(nValue); + + // index of viewBox + ui.viewBox->setCurrentIndex(Settings->value("viewBox", VIEW_THREADED).toInt()); + + // state of thread tree + pHeader->restoreState(Settings->value("ThreadTree").toByteArray()); + + // state of splitter + ui.splitter->restoreState(Settings->value("Splitter").toByteArray()); + ui.threadSplitter->restoreState(Settings->value("threadSplitter").toByteArray()); + } else { + // save settings + + // state of thread tree + Settings->setValue("ThreadTree", pHeader->saveState()); + + // state of splitter + Settings->setValue("Splitter", ui.splitter->saveState()); + Settings->setValue("threadSplitter", ui.threadSplitter->saveState()); + } + + ui.forumTreeWidget->processSettings(Settings, bLoad); + + Settings->endGroup(); + m_bProcessSettings = false; +} + +void ForumsV2Dialog::forumListCustomPopupMenu( QPoint /*point*/ ) +{ + QMenu contextMnu( this ); + + QAction *action = contextMnu.addAction(QIcon(IMAGE_SUBSCRIBE), tr("Subscribe to Forum"), this, SLOT(subscribeToForum())); + action->setDisabled (mCurrForumId.empty() || IS_FORUM_SUBSCRIBED(subscribeFlags)); + + action = contextMnu.addAction(QIcon(IMAGE_UNSUBSCRIBE), tr("Unsubscribe to Forum"), this, SLOT(unsubscribeToForum())); + action->setEnabled (!mCurrForumId.empty() && IS_FORUM_SUBSCRIBED(subscribeFlags)); + + contextMnu.addSeparator(); + + contextMnu.addAction(QIcon(IMAGE_NEWFORUM), tr("New Forum"), this, SLOT(newforum())); + + action = contextMnu.addAction(QIcon(IMAGE_INFO), tr("Show Forum Details"), this, SLOT(showForumDetails())); + action->setEnabled (!mCurrForumId.empty ()); + + action = contextMnu.addAction(QIcon(":/images/settings16.png"), tr("Edit Forum Details"), this, SLOT(editForumDetails())); + action->setEnabled (!mCurrForumId.empty () && IS_FORUM_ADMIN(subscribeFlags)); + + QAction *shareKeyAct = new QAction(QIcon(":/images/gpgp_key_generate.png"), tr("Share Forum"), &contextMnu); + connect( shareKeyAct, SIGNAL( triggered() ), this, SLOT( shareKey() ) ); + shareKeyAct->setEnabled(!mCurrForumId.empty() && IS_FORUM_ADMIN(subscribeFlags)); + contextMnu.addAction( shareKeyAct); + + QAction *restoreKeysAct = new QAction(QIcon(":/images/settings16.png"), tr("Restore Publish Rights for Forum" ), &contextMnu); + connect( restoreKeysAct , SIGNAL( triggered() ), this, SLOT( restoreForumKeys() ) ); + restoreKeysAct->setEnabled(!mCurrForumId.empty() && !IS_FORUM_ADMIN(subscribeFlags)); + contextMnu.addAction( restoreKeysAct); + + action = contextMnu.addAction(QIcon(IMAGE_COPYLINK), tr("Copy RetroShare Link"), this, SLOT(copyForumLink())); + action->setEnabled(!mCurrForumId.empty()); + + contextMnu.addSeparator(); + + action = contextMnu.addAction(QIcon(":/images/message-mail-read.png"), tr("Mark all as read"), this, SLOT(markMsgAsReadAll())); + action->setEnabled (!mCurrForumId.empty () && IS_FORUM_SUBSCRIBED(subscribeFlags)); + + action = contextMnu.addAction(QIcon(":/images/message-mail.png"), tr("Mark all as unread"), this, SLOT(markMsgAsUnreadAll())); + action->setEnabled (!mCurrForumId.empty () && IS_FORUM_SUBSCRIBED(subscribeFlags)); + +#ifdef DEBUG_FORUMS + contextMnu.addSeparator(); + action = contextMnu.addAction("Generate mass data", this, SLOT(generateMassData())); + action->setEnabled (!mCurrForumId.empty() && IS_FORUM_SUBSCRIBED(subscribeFlags)); +#endif + + contextMnu.exec(QCursor::pos()); +} + +void ForumsV2Dialog::threadListCustomPopupMenu( QPoint /*point*/ ) +{ + if (mThreadLoading) { + return; + } + + QMenu contextMnu( this ); + + QAction *replyAct = new QAction(QIcon(IMAGE_MESSAGEREPLY), tr( "Reply" ), &contextMnu ); + connect( replyAct , SIGNAL( triggered() ), this, SLOT( createmessage() ) ); + + QAction *newthreadAct = new QAction(QIcon(IMAGE_DOWNLOADALL), tr( "Start New Thread" ), &contextMnu ); + newthreadAct->setEnabled (IS_FORUM_SUBSCRIBED(subscribeFlags)); + connect( newthreadAct , SIGNAL( triggered() ), this, SLOT( createthread() ) ); + + QAction *replyauthorAct = new QAction(QIcon(IMAGE_MESSAGEREPLY), tr( "Reply to Author" ), &contextMnu ); + connect( replyauthorAct , SIGNAL( triggered() ), this, SLOT( replytomessage() ) ); + + QAction* expandAll = new QAction(tr( "Expand all" ), &contextMnu ); + connect( expandAll , SIGNAL( triggered() ), ui.threadTreeWidget, SLOT (expandAll()) ); + + QAction* collapseAll = new QAction(tr( "Collapse all" ), &contextMnu ); + connect( collapseAll , SIGNAL( triggered() ), ui.threadTreeWidget, SLOT(collapseAll()) ); + + QAction *markMsgAsRead = new QAction(QIcon(":/images/message-mail-read.png"), tr("Mark as read"), &contextMnu); + connect(markMsgAsRead , SIGNAL(triggered()), this, SLOT(markMsgAsRead())); + + QAction *markMsgAsReadChildren = new QAction(QIcon(":/images/message-mail-read.png"), tr("Mark as read") + " (" + tr ("with children") + ")", &contextMnu); + connect(markMsgAsReadChildren, SIGNAL(triggered()), this, SLOT(markMsgAsReadChildren())); + + QAction *markMsgAsUnread = new QAction(QIcon(":/images/message-mail.png"), tr("Mark as unread"), &contextMnu); + connect(markMsgAsUnread , SIGNAL(triggered()), this, SLOT(markMsgAsUnread())); + + QAction *markMsgAsUnreadChildren = new QAction(QIcon(":/images/message-mail.png"), tr("Mark as unread") + " (" + tr ("with children") + ")", &contextMnu); + connect(markMsgAsUnreadChildren , SIGNAL(triggered()), this, SLOT(markMsgAsUnreadChildren())); + + if (IS_FORUM_SUBSCRIBED(subscribeFlags)) { + QList Rows; + QList RowsRead; + QList RowsUnread; + int nCount = getSelectedMsgCount (&Rows, &RowsRead, &RowsUnread); + + if (RowsUnread.size() == 0) { + + markMsgAsRead->setDisabled(true); + } + if (RowsRead.size() == 0) { + markMsgAsUnread->setDisabled(true); + } + + bool bHasUnreadChildren = false; + bool bHasReadChildren = false; + int nRowCount = Rows.count(); + for (int i = 0; i < nRowCount; i++) { + if (bHasUnreadChildren || Rows[i]->data(COLUMN_THREAD_DATA, ROLE_THREAD_UNREADCHILDREN).toBool()) { + bHasUnreadChildren = true; + } + if (bHasReadChildren || Rows[i]->data(COLUMN_THREAD_DATA, ROLE_THREAD_READCHILDREN).toBool()) { + bHasReadChildren = true; + } + } + markMsgAsReadChildren->setEnabled(bHasUnreadChildren); + markMsgAsUnreadChildren->setEnabled(bHasReadChildren); + + if (nCount == 1) { + replyAct->setEnabled (true); + replyauthorAct->setEnabled (true); + } else { + replyAct->setDisabled (true); + replyauthorAct->setDisabled (true); + } + } else { + markMsgAsRead->setDisabled(true); + markMsgAsReadChildren->setDisabled(true); + markMsgAsUnread->setDisabled(true); + markMsgAsUnreadChildren->setDisabled(true); + replyAct->setDisabled (true); + replyauthorAct->setDisabled (true); + } + + contextMnu.addAction( replyAct); + contextMnu.addAction( newthreadAct); + contextMnu.addAction( replyauthorAct); + QAction* action = contextMnu.addAction(QIcon(IMAGE_COPYLINK), tr( "Copy RetroShare Link"), this, SLOT(copyMessageLink())); + action->setEnabled(!mCurrForumId.empty() && !mCurrThreadId.empty()); + contextMnu.addSeparator(); + contextMnu.addAction(markMsgAsRead); + contextMnu.addAction(markMsgAsReadChildren); + contextMnu.addAction(markMsgAsUnread); + contextMnu.addAction(markMsgAsUnreadChildren); + contextMnu.addSeparator(); + contextMnu.addAction( expandAll); + contextMnu.addAction( collapseAll); + + contextMnu.exec(QCursor::pos()); +} + +bool ForumsV2Dialog::eventFilter(QObject *obj, QEvent *event) +{ + if (obj == ui.threadTreeWidget) { + if (event->type() == QEvent::KeyPress) { + QKeyEvent *keyEvent = static_cast(event); + if (keyEvent && keyEvent->key() == Qt::Key_Space) { + // Space pressed + QTreeWidgetItem *item = ui.threadTreeWidget->currentItem (); + clickedThread (item, COLUMN_THREAD_READ); + return true; // eat event + } + } + } + // pass the event on to the parent class + return RsAutoUpdatePage::eventFilter(obj, event); +} + +void ForumsV2Dialog::restoreForumKeys(void) +{ + rsForumsV2->groupRestoreKeys(mCurrForumId); +} + +void ForumsV2Dialog::togglethreadview() +{ + // save state of button + Settings->setValueToGroup("ForumsV2Dialog", "expandButton", ui.expandButton->isChecked()); + + togglethreadview_internal(); +} + +void ForumsV2Dialog::togglethreadview_internal() +{ + if (ui.expandButton->isChecked()) { + ui.postText->setVisible(true); + ui.expandButton->setIcon(QIcon(QString(":/images/edit_remove24.png"))); + ui.expandButton->setToolTip(tr("Hide")); + } else { + ui.postText->setVisible(false); + ui.expandButton->setIcon(QIcon(QString(":/images/edit_add24.png"))); + ui.expandButton->setToolTip(tr("Expand")); + } +} + +void ForumsV2Dialog::updateDisplay() +{ + std::list forumIds; + std::list::iterator it; + if (!rsForumsV2) + return; + + if (rsForumsV2->groupsChanged(forumIds)) + { + /* update Forums List */ + insertForums(); + + it = std::find(forumIds.begin(), forumIds.end(), mCurrForumId); + if (it != forumIds.end()) + { + /* update threads as well */ + insertThreads(); + } + } +} + +static void CleanupItems (QList &Items) +{ + QList::iterator Item; + for (Item = Items.begin (); Item != Items.end (); Item++) { + if (*Item) { + delete (*Item); + } + } + Items.clear(); +} + +void ForumsV2Dialog::forumInfoToGroupItemInfo(const RsGroupMetaData &forumInfo, GroupItemInfo &groupItemInfo) +//void ForumsV2Dialog::forumInfoToGroupItemInfo(const ForumInfo &forumInfo, GroupItemInfo &groupItemInfo) +{ + + groupItemInfo.id = QString::fromStdString(forumInfo.mGroupId); + groupItemInfo.name = QString::fromUtf8(forumInfo.mGroupName.c_str()); + //groupItemInfo.description = QString::fromUtf8(forumInfo.forumDesc); + groupItemInfo.popularity = forumInfo.mPop; + groupItemInfo.lastpost = QDateTime::fromTime_t(forumInfo.mLastPost); + + if (forumInfo.mGroupFlags & RS_DISTRIB_AUTHEN_REQ) { + groupItemInfo.name += " (" + tr("AUTHD") + ")"; + groupItemInfo.icon = QIcon(IMAGE_FORUMAUTHD); + } else { + groupItemInfo.icon = QIcon(IMAGE_FORUM); + } + +// groupItemInfo.id = QString::fromStdString(forumInfo.forumId); +// groupItemInfo.name = QString::fromStdWString(forumInfo.forumName); +// groupItemInfo.description = QString::fromStdWString(forumInfo.forumDesc); +// groupItemInfo.popularity = forumInfo.pop; +// groupItemInfo.lastpost = QDateTime::fromTime_t(forumInfo.lastPost); +// +// if (forumInfo.forumFlags & RS_DISTRIB_AUTHEN_REQ) { +// groupItemInfo.name += " (" + tr("AUTHD") + ")"; +// groupItemInfo.icon = QIcon(IMAGE_FORUMAUTHD); +// } else { +// groupItemInfo.icon = QIcon(IMAGE_FORUM); +// } +} + + +/***** INSERT FORUM LISTS *****/ +void ForumsV2Dialog::insertForumsData(const std::list &forumList) +{ + std::list::const_iterator it; + + QList adminList; + QList subList; + QList popList; + QList otherList; + std::multimap popMap; + + for (it = forumList.begin(); it != forumList.end(); it++) { + /* sort it into Publish (Own), Subscribed, Popular and Other */ + uint32_t flags = it->mSubscribeFlags; + + GroupItemInfo groupItemInfo; + forumInfoToGroupItemInfo(*it, groupItemInfo); + + if (flags & RS_DISTRIB_ADMIN) { + adminList.push_back(groupItemInfo); + } else if (flags & RS_DISTRIB_SUBSCRIBED) { + /* subscribed forum */ + subList.push_back(groupItemInfo); + } else { + /* rate the others by popularity */ + popMap.insert(std::make_pair(it->mPop, groupItemInfo)); + } + } + + /* 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++) ; + if (rit != popMap.rend()) { + popLimit = rit->first; + } + + for (rit = popMap.rbegin(); rit != popMap.rend(); rit++) { + if (rit->second.popularity < (int) popLimit) { + otherList.append(rit->second); + } else { + popList.append(rit->second); + } + } + + /* now we can add them in as a tree! */ + ui.forumTreeWidget->fillGroupItems(yourForums, adminList); + ui.forumTreeWidget->fillGroupItems(subscribedForums, subList); + ui.forumTreeWidget->fillGroupItems(popularForums, popList); + ui.forumTreeWidget->fillGroupItems(otherForums, otherList); + + updateMessageSummaryList(""); +} + +void ForumsV2Dialog::changedForum(const QString &id) +{ + mCurrForumId = id.toStdString(); + + insertThreads(); +} + +void ForumsV2Dialog::changedThread () +{ + if (mThreadLoading) { + return; + } + + /* just grab the ids of the current item */ + QTreeWidgetItem *curr = ui.threadTreeWidget->currentItem(); + + if ((!curr) || (!curr->isSelected())) { + mCurrThreadId = ""; + } else { + mCurrThreadId = curr->data(COLUMN_THREAD_DATA, ROLE_THREAD_MSGID).toString().toStdString(); + } + insertPost(); +} + +void ForumsV2Dialog::clickedThread (QTreeWidgetItem *item, int column) +{ + if (mCurrForumId.empty() || !IS_FORUM_SUBSCRIBED(subscribeFlags)) { + return; + } + + if (item == NULL) { + return; + } + + if (column == COLUMN_THREAD_READ) { + QList Rows; + Rows.append(item); + uint32_t status = item->data(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); + setMsgAsReadUnread(Rows, IS_UNREAD(status)); + return; + } +} + +void ForumsV2Dialog::CalculateIconsAndFonts(QTreeWidgetItem *pItem, bool &bHasReadChilddren, bool &bHasUnreadChilddren) +{ + uint32_t status = pItem->data(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); + + bool bUnread = IS_UNREAD(status); + bool missing = pItem->data(COLUMN_THREAD_DATA, ROLE_THREAD_MISSING).toBool(); + + // set icon + if (missing) { + pItem->setIcon(COLUMN_THREAD_READ, QIcon()); + pItem->setIcon(COLUMN_THREAD_TITLE, QIcon()); + } else { + if (bUnread) { + pItem->setIcon(COLUMN_THREAD_READ, QIcon(":/images/message-state-unread.png")); + } else { + pItem->setIcon(COLUMN_THREAD_READ, QIcon(":/images/message-state-read.png")); + } + if (status & RSGXS_MSG_STATUS_READ) { + pItem->setIcon(COLUMN_THREAD_TITLE, QIcon()); + } else { + pItem->setIcon(COLUMN_THREAD_TITLE, QIcon(":/images/message-state-new.png")); + } + } + + int nItem; + int nItemCount = pItem->childCount(); + + bool bMyReadChilddren = false; + bool bMyUnreadChilddren = false; + + for (nItem = 0; nItem < nItemCount; nItem++) { + CalculateIconsAndFonts(pItem->child(nItem), bMyReadChilddren, bMyUnreadChilddren); + } + + // set font + for (int i = 0; i < COLUMN_THREAD_COUNT; i++) { + QFont qf = pItem->font(i); + + if (!IS_FORUM_SUBSCRIBED(subscribeFlags)) { + qf.setBold(false); + pItem->setTextColor(i, Qt::black); + } else if (bUnread) { + qf.setBold(true); + pItem->setTextColor(i, Qt::black); + } else if (bMyUnreadChilddren) { + qf.setBold(true); + pItem->setTextColor(i, Qt::gray); + } else { + qf.setBold(false); + pItem->setTextColor(i, Qt::gray); + } + if (missing) { + /* Missing message */ + pItem->setTextColor(i, Qt::darkRed); + } + pItem->setFont(i, qf); + } + + pItem->setData(COLUMN_THREAD_DATA, ROLE_THREAD_READCHILDREN, bHasReadChilddren || bMyReadChilddren); + pItem->setData(COLUMN_THREAD_DATA, ROLE_THREAD_UNREADCHILDREN, bHasUnreadChilddren || bMyUnreadChilddren); + + bHasReadChilddren = bHasReadChilddren || bMyReadChilddren || !bUnread; + bHasUnreadChilddren = bHasUnreadChilddren || bMyUnreadChilddren || bUnread; +} + +void ForumsV2Dialog::CalculateIconsAndFonts(QTreeWidgetItem *pItem /*= NULL*/) +{ + bool bDummy1 = false; + bool bDummy2 = false; + + if (pItem) { + CalculateIconsAndFonts(pItem, bDummy1, bDummy2); + return; + } + + int nItem; + int nItemCount = ui.threadTreeWidget->topLevelItemCount(); + + for (nItem = 0; nItem < nItemCount; nItem++) { + bDummy1 = false; + bDummy2 = false; + CalculateIconsAndFonts(ui.threadTreeWidget->topLevelItem(nItem), bDummy1, bDummy2); + } +} + +void ForumsV2Dialog::fillThreadFinished() +{ +#ifdef DEBUG_FORUMS + std::cerr << "ForumsV2Dialog::fillThreadFinished" << std::endl; +#endif + + // This is now only called with a successful Load. + // cleanup of incomplete is handled elsewhere. + + // current thread has finished, hide progressbar and release thread + ui.progressBar->hide(); + ui.progLayOutTxt->hide(); + ui.progressBarLayOut->setEnabled(false); + +#ifdef DEBUG_FORUMS + std::cerr << "ForumsV2Dialog::fillThreadFinished Add messages" << std::endl; +#endif + /* add all messages in! */ + if (lastViewType != mThreadLoad.ViewType || lastForumID != mCurrForumId) + { + ui.threadTreeWidget->clear(); + lastViewType = mThreadLoad.ViewType; + lastForumID = mCurrForumId; + ui.threadTreeWidget->insertTopLevelItems(0, mThreadLoad.Items); + + // clear list + mThreadLoad.Items.clear(); + } + else + { + FillThreads (mThreadLoad.Items, mThreadLoad.ExpandNewMessages, mThreadLoad.ItemToExpand); + + // cleanup list + CleanupItems (mThreadLoad.Items); + } + + + + if (mThreadLoad.FocusMsgId.empty() == false) + { + /* Search exisiting item */ + QTreeWidgetItemIterator itemIterator(ui.threadTreeWidget); + QTreeWidgetItem *item = NULL; + while ((item = *itemIterator) != NULL) + { + itemIterator++; + + if (item->data(COLUMN_THREAD_DATA, ROLE_THREAD_MSGID).toString().toStdString() == mThreadLoad.FocusMsgId) + { + ui.threadTreeWidget->setCurrentItem(item); + ui.threadTreeWidget->setFocus(); + break; + } + } + } + + QList::iterator Item; + for (Item = mThreadLoad.ItemToExpand.begin(); Item != mThreadLoad.ItemToExpand.end(); Item++) + { + if ((*Item)->isHidden() == false) + { + (*Item)->setExpanded(true); + } + } + mThreadLoad.ItemToExpand.clear(); + + if (ui.filterPatternLineEdit->text().isEmpty() == false) + { + FilterItems(); + } + + insertPost (); + CalculateIconsAndFonts(); + + ui.newthreadButton->setEnabled (IS_FORUM_SUBSCRIBED(subscribeFlags)); + + mThreadLoading = false; + +#ifdef DEBUG_FORUMS + std::cerr << "ForumsV2Dialog::fillThreadFinished done" << std::endl; +#endif +} + +void ForumsV2Dialog::fillThreadProgress(int current, int count) +{ + // show fill progress + if (count) { + ui.progressBar->setValue(current * ui.progressBar->maximum() / count); + } + +} + +void ForumsV2Dialog::insertThreads() +{ +#ifdef DEBUG_FORUMS + /* get the current Forum */ + std::cerr << "ForumsV2Dialog::insertThreads()" << std::endl; +#endif + + subscribeFlags = 0; + + ui.newmessageButton->setEnabled (false); + ui.newthreadButton->setEnabled (false); + + ui.postText->clear(); + ui.threadTitle->clear(); + + if (mCurrForumId.empty()) + { + /* not an actual forum - clear */ + ui.threadTreeWidget->clear(); + /* when no Thread selected - clear */ + ui.forumName->clear(); + /* clear last stored forumID */ + mCurrForumId.erase(); + lastForumID.erase(); + +#ifdef DEBUG_FORUMS + std::cerr << "ForumsV2Dialog::insertThreads() Current Thread Invalid" << std::endl; +#endif + + return; + } + + // Get Current Forum Info... then complete insertForumThreads(). + requestGroupSummary_CurrentForum(mCurrForumId); +} + + +void ForumsV2Dialog::insertForumThreads(const RsGroupMetaData &fi) +{ + subscribeFlags = fi.mSubscribeFlags; + ui.forumName->setText(QString::fromUtf8(fi.mGroupName.c_str())); + + ui.progressBarLayOut->setEnabled(true); + + ui.progLayOutTxt->show(); + ui.progressBar->show(); + +#ifdef DEBUG_FORUMS + std::cerr << "ForumsV2Dialog::insertThreads() Start filling Forum threads" << std::endl; +#endif + + loadCurrentForumThreads(fi.mGroupId); +} + + + + +void ForumsV2Dialog::FillThreads(QList &ThreadList, bool expandNewMessages, QList &itemToExpand) +{ +#ifdef DEBUG_FORUMS + std::cerr << "ForumsV2Dialog::FillThreads()" << std::endl; +#endif + + int Index = 0; + QTreeWidgetItem *Thread; + QList::iterator NewThread; + + // delete not existing + while (Index < ui.threadTreeWidget->topLevelItemCount ()) { + Thread = ui.threadTreeWidget->topLevelItem (Index); + + // search existing new thread + int Found = -1; + for (NewThread = ThreadList.begin (); NewThread != ThreadList.end (); NewThread++) { + if (Thread->data (COLUMN_THREAD_DATA, ROLE_THREAD_MSGID) == (*NewThread)->data (COLUMN_THREAD_DATA, ROLE_THREAD_MSGID)) { + // found it + Found = Index; + break; + } + } + if (Found >= 0) { + Index++; + } else { + delete (ui.threadTreeWidget->takeTopLevelItem (Index)); + } + } + + // iterate all new threads + for (NewThread = ThreadList.begin (); NewThread != ThreadList.end (); NewThread++) { + // search existing thread + int Found = -1; + int Count = ui.threadTreeWidget->topLevelItemCount (); + for (Index = 0; Index < Count; Index++) { + Thread = ui.threadTreeWidget->topLevelItem (Index); + if (Thread->data (COLUMN_THREAD_DATA, ROLE_THREAD_MSGID) == (*NewThread)->data (COLUMN_THREAD_DATA, ROLE_THREAD_MSGID)) { + // found it + Found = Index; + break; + } + } + + if (Found >= 0) { + // set child data + int i; + for (i = 0; i < COLUMN_THREAD_COUNT; i++) { + Thread->setText (i, (*NewThread)->text (i)); + } + for (i = 0; i < ROLE_THREAD_COUNT; i++) { + Thread->setData (COLUMN_THREAD_DATA, Qt::UserRole + i, (*NewThread)->data (COLUMN_THREAD_DATA, Qt::UserRole + i)); + } + + // fill recursive + FillChildren (Thread, *NewThread, expandNewMessages, itemToExpand); + } else { + // add new thread + ui.threadTreeWidget->addTopLevelItem (*NewThread); + Thread = *NewThread; + *NewThread = NULL; + } + + uint32_t status = Thread->data (COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); + if (expandNewMessages && IS_UNREAD(status)) { + QTreeWidgetItem *pParent = Thread; + while ((pParent = pParent->parent()) != NULL) { + if (std::find(itemToExpand.begin(), itemToExpand.end(), pParent) == itemToExpand.end()) { + itemToExpand.push_back(pParent); + } + } + } + } + +#ifdef DEBUG_FORUMS + std::cerr << "ForumsV2Dialog::FillThreads() done" << std::endl; +#endif +} + +void ForumsV2Dialog::FillChildren(QTreeWidgetItem *Parent, QTreeWidgetItem *NewParent, bool expandNewMessages, QList &itemToExpand) +{ + int Index = 0; + int NewIndex; + int NewCount = NewParent->childCount(); + + QTreeWidgetItem *Child; + QTreeWidgetItem *NewChild; + + // delete not existing + while (Index < Parent->childCount ()) { + Child = Parent->child (Index); + + // search existing new child + int Found = -1; + int Count = NewParent->childCount(); + for (NewIndex = 0; NewIndex < Count; NewIndex++) { + NewChild = NewParent->child (NewIndex); + if (NewChild->data (COLUMN_THREAD_DATA, ROLE_THREAD_MSGID) == Child->data (COLUMN_THREAD_DATA, ROLE_THREAD_MSGID)) { + // found it + Found = Index; + break; + } + } + if (Found >= 0) { + Index++; + } else { + delete (Parent->takeChild (Index)); + } + } + + // iterate all new children + for (NewIndex = 0; NewIndex < NewCount; NewIndex++) { + NewChild = NewParent->child (NewIndex); + + // search existing child + int Found = -1; + int Count = Parent->childCount(); + for (Index = 0; Index < Count; Index++) { + Child = Parent->child (Index); + if (Child->data (COLUMN_THREAD_DATA, ROLE_THREAD_MSGID) == NewChild->data (COLUMN_THREAD_DATA, ROLE_THREAD_MSGID)) { + // found it + Found = Index; + break; + } + } + + if (Found >= 0) { + // set child data + int i; + for (i = 0; i < COLUMN_THREAD_COUNT; i++) { + Child->setText (i, NewChild->text (i)); + } + for (i = 0; i < ROLE_THREAD_COUNT; i++) { + Child->setData (COLUMN_THREAD_DATA, Qt::UserRole + i, NewChild->data (COLUMN_THREAD_DATA, Qt::UserRole + i)); + } + + // fill recursive + FillChildren (Child, NewChild, expandNewMessages, itemToExpand); + } else { + // add new child + Child = NewParent->takeChild(NewIndex); + Parent->addChild (Child); + NewIndex--; + NewCount--; + } + + uint32_t status = Child->data (COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); + if (expandNewMessages && IS_UNREAD(status)) { + QTreeWidgetItem *pParent = Child; + while ((pParent = pParent->parent()) != NULL) { + if (std::find(itemToExpand.begin(), itemToExpand.end(), pParent) == itemToExpand.end()) { + itemToExpand.push_back(pParent); + } + } + } + } +} + +void ForumsV2Dialog::insertPost() +{ + if ((mCurrForumId == "") || (mCurrThreadId == "")) + { + ui.postText->setText(""); + ui.threadTitle->setText(""); + ui.previousButton->setEnabled(false); + ui.nextButton->setEnabled(false); + ui.newmessageButton->setEnabled (false); + return; + } + + QTreeWidgetItem *curr = ui.threadTreeWidget->currentItem(); + if (curr) { + QTreeWidgetItem *Parent = curr->parent (); + int Index = Parent ? Parent->indexOfChild (curr) : ui.threadTreeWidget->indexOfTopLevelItem (curr); + int Count = Parent ? Parent->childCount () : ui.threadTreeWidget->topLevelItemCount (); + ui.previousButton->setEnabled (Index > 0); + ui.nextButton->setEnabled (Index < Count - 1); + } else { + // there is something wrong + ui.previousButton->setEnabled(false); + ui.nextButton->setEnabled(false); + return; + } + + ui.newmessageButton->setEnabled (IS_FORUM_SUBSCRIBED(subscribeFlags) && mCurrThreadId.empty() == false); + + /* blank text, incase we get nothing */ + ui.postText->setText(""); + /* request Post */ + + requestMsgData_InsertPost(mCurrThreadId); + +} + + + +void ForumsV2Dialog::insertPostData(const RsForumV2Msg &msg) +{ + /* As some time has elapsed since request - check that this is still the current msg. + * otherwise, another request will fill the data + */ + + if ((msg.mMeta.mGroupId != mCurrForumId) || (msg.mMeta.mMsgId != mCurrThreadId)) + { + std::cerr << "ForumsV2Dialog::insertPostData() Ignoring Invalid Data...."; + std::cerr << std::endl; + std::cerr << "\t CurrForumId: " << mCurrForumId << " != msg.GroupId: " << msg.mMeta.mGroupId; + std::cerr << std::endl; + std::cerr << "\t or CurrThdId: " << mCurrThreadId << " != msg.MsgId: " << msg.mMeta.mMsgId; + std::cerr << std::endl; + std::cerr << std::endl; + return; + } + + QTreeWidgetItem *curr = ui.threadTreeWidget->currentItem(); + + bool bSetToReadOnActive = Settings->getForumMsgSetToReadOnActivate(); + uint32_t status = curr->data(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); + + QList Row; + Row.append(curr); + if (status & RSGXS_MSG_STATUS_READ) { + if (bSetToReadOnActive && (status & RSGXS_MSG_STATUS_UNREAD_BY_USER)) { + /* set to read */ + setMsgAsReadUnread(Row, true); + } + } else { + /* set to read */ + if (bSetToReadOnActive) { + setMsgAsReadUnread(Row, true); + } else { + /* set to unread by user */ + setMsgAsReadUnread(Row, false); + } + } + + QString extraTxt = RsHtml::formatText(QString::fromUtf8(msg.mMsg.c_str()), RSHTML_FORMATTEXT_EMBED_SMILEYS | RSHTML_FORMATTEXT_EMBED_LINKS); + + ui.postText->setHtml(extraTxt); + ui.threadTitle->setText(QString::fromUtf8(msg.mMeta.mMsgName.c_str())); +} + + +void ForumsV2Dialog::previousMessage () +{ + QTreeWidgetItem *Item = ui.threadTreeWidget->currentItem (); + if (Item == NULL) { + return; + } + + QTreeWidgetItem *Parent = Item->parent (); + int Index = Parent ? Parent->indexOfChild (Item) : ui.threadTreeWidget->indexOfTopLevelItem (Item); + if (Index > 0) { + QTreeWidgetItem *Previous = Parent ? Parent->child (Index - 1) : ui.threadTreeWidget->topLevelItem (Index - 1); + if (Previous) { + ui.threadTreeWidget->setCurrentItem (Previous); + } + } +} + +void ForumsV2Dialog::nextMessage () +{ + QTreeWidgetItem *Item = ui.threadTreeWidget->currentItem (); + if (Item == NULL) { + return; + } + + QTreeWidgetItem *Parent = Item->parent (); + int Index = Parent ? Parent->indexOfChild (Item) : ui.threadTreeWidget->indexOfTopLevelItem (Item); + int Count = Parent ? Parent->childCount () : ui.threadTreeWidget->topLevelItemCount (); + if (Index < Count - 1) { + QTreeWidgetItem *Next = Parent ? Parent->child (Index + 1) : ui.threadTreeWidget->topLevelItem (Index + 1); + if (Next) { + ui.threadTreeWidget->setCurrentItem (Next); + } + } +} + +void ForumsV2Dialog::downloadAllFiles() +{ + QStringList urls; + if (RsHtml::findAnchors(ui.postText->toHtml(), urls) == false) { + return; + } + + if (urls.count() == 0) { + return; + } + + RetroShareLink::process(urls, RetroShareLink::TYPE_FILE/*, true*/); +} + +void ForumsV2Dialog::nextUnreadMessage() +{ + QTreeWidgetItem* currentItem = ui.threadTreeWidget->currentItem(); + if( !currentItem ) + { + currentItem = ui.threadTreeWidget->topLevelItem(0); + if( !currentItem ) + return; + } + + do + { + uint32_t status = currentItem->data(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); + if( IS_UNREAD(status) ) + { + ui.threadTreeWidget->setCurrentItem(currentItem); + return; + } + } while( (currentItem = ui.threadTreeWidget->itemBelow(currentItem)) != NULL ); +} + +// TODO +#if 0 +void ForumsV2Dialog::removemessage() +{ + //std::cerr << "ForumsV2Dialog::removemessage()" << std::endl; + std::string cid, mid; + if (!getCurrentMsg(cid, mid)) + { + //std::cerr << "ForumsV2Dialog::removemessage()"; + //std::cerr << " No Message selected" << std::endl; + return; + } + + rsMsgs -> MessageDelete(mid); +} +#endif + +/* get selected messages + the messages tree is single selected, but who knows ... */ +int ForumsV2Dialog::getSelectedMsgCount(QList *pRows, QList *pRowsRead, QList *pRowsUnread) +{ + if (pRowsRead) pRowsRead->clear(); + if (pRowsUnread) pRowsUnread->clear(); + + QList selectedItems = ui.threadTreeWidget->selectedItems(); + for(QList::iterator it = selectedItems.begin(); it != selectedItems.end(); it++) { + if (pRows) pRows->append(*it); + if (pRowsRead || pRowsUnread) { + uint32_t status = (*it)->data(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); + if (IS_UNREAD(status)) { + if (pRowsUnread) pRowsUnread->append(*it); + } else { + if (pRowsRead) pRowsRead->append(*it); + } + } + } + + return selectedItems.size(); +} + +void ForumsV2Dialog::setMsgAsReadUnread(QList &Rows, bool bRead) +{ + QList::iterator Row; + std::list changedItems; + + for (Row = Rows.begin(); Row != Rows.end(); Row++) { + if ((*Row)->data(COLUMN_THREAD_DATA, ROLE_THREAD_MISSING).toBool()) { + /* Missing message */ + continue; + } + + uint32_t status = (*Row)->data(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); + + /* set always as read ... */ + uint32_t statusNew = status | RSGXS_MSG_STATUS_READ; + if (bRead) { + /* ... and as read by user */ + statusNew &= ~RSGXS_MSG_STATUS_UNREAD_BY_USER; + } else { + /* ... and as unread by user */ + statusNew |= RSGXS_MSG_STATUS_UNREAD_BY_USER; + } + if (status != statusNew) { + std::string msgId = (*Row)->data(COLUMN_THREAD_DATA, ROLE_THREAD_MSGID).toString().toStdString(); + rsForumsV2->setMessageStatus(msgId, statusNew, RSGXS_MSG_STATUS_READ | RSGXS_MSG_STATUS_UNREAD_BY_USER); + + (*Row)->setData(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS, statusNew); + + QTreeWidgetItem *parentItem = *Row; + while (parentItem->parent()) { + parentItem = parentItem->parent(); + } + if (std::find(changedItems.begin(), changedItems.end(), parentItem) == changedItems.end()) { + changedItems.push_back(parentItem); + } + } + } + + if (changedItems.size()) { + for (std::list::iterator it = changedItems.begin(); it != changedItems.end(); it++) { + CalculateIconsAndFonts(*it); + } + updateMessageSummaryList(mCurrForumId); + } +} + +void ForumsV2Dialog::markMsgAsReadUnread (bool bRead, bool bChildren, bool bForum) +{ + if (mCurrForumId.empty() || !IS_FORUM_SUBSCRIBED(subscribeFlags)) { + return; + } + + /* get selected messages */ + QList Rows; + if (bForum) { + int itemCount = ui.threadTreeWidget->topLevelItemCount(); + for (int item = 0; item < itemCount; item++) { + Rows.push_back(ui.threadTreeWidget->topLevelItem(item)); + } + } else { + getSelectedMsgCount (&Rows, NULL, NULL); + } + + if (bChildren) { + /* add children */ + QList AllRows; + + while (Rows.isEmpty() == false) { + QTreeWidgetItem *pRow = Rows.takeFirst(); + + /* add only items with the right state or with not RSGXS_MSG_STATUS_READ */ + uint32_t status = pRow->data(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); + if (IS_UNREAD(status) == bRead || (status & RSGXS_MSG_STATUS_READ) == 0) { + AllRows.append(pRow); + } + + for (int i = 0; i < pRow->childCount(); i++) { + /* add child to main list and let the main loop do the work */ + Rows.append(pRow->child(i)); + } + } + + if (AllRows.isEmpty()) { + /* nothing to do */ + return; + } + + setMsgAsReadUnread (AllRows, bRead); + + return; + } + + setMsgAsReadUnread (Rows, bRead); +} + +void ForumsV2Dialog::markMsgAsRead() +{ + markMsgAsReadUnread(true, false, false); +} + +void ForumsV2Dialog::markMsgAsReadChildren() +{ + markMsgAsReadUnread(true, true, false); +} + +void ForumsV2Dialog::markMsgAsReadAll() +{ + markMsgAsReadUnread(true, true, true); +} + +void ForumsV2Dialog::markMsgAsUnread() +{ + markMsgAsReadUnread(false, false, false); +} + +void ForumsV2Dialog::markMsgAsUnreadChildren() +{ + markMsgAsReadUnread(false, true, false); +} + +void ForumsV2Dialog::markMsgAsUnreadAll() +{ + markMsgAsReadUnread(false, true, true); +} + +void ForumsV2Dialog::copyForumLink() +{ + if (mCurrForumId.empty()) { + return; + } + +// THIS CODE CALLS getForumInfo() to verify that the Ids are valid. +// As we are switching to Request/Response this is now harder to do... +// So not bothering any more - shouldn't be necessary. +// IF we get errors - fix them, rather than patching here. +#if 0 + ForumInfo fi; + if (rsForumsV2->getForumInfo(mCurrForumId, fi)) { + RetroShareLink link; + if (link.createForum(fi.forumId, "")) { + QList urls; + urls.push_back(link); + RSLinkClipboard::copyLinks(urls); + } + } +#endif + + { + RetroShareLink link; + if (link.createForum(mCurrForumId, "")) + { + QList urls; + urls.push_back(link); + RSLinkClipboard::copyLinks(urls); + } + } +} + + + + +void ForumsV2Dialog::copyMessageLink() +{ + if (mCurrForumId.empty() || mCurrThreadId.empty()) { + return; + } + +// SEE NOTE In fn above. +#if 0 + ForumInfo fi; + if (rsForumsV2->getForumInfo(mCurrForumId, fi)) { + RetroShareLink link; + if (link.createForum(mCurrForumId, mCurrThreadId)) { + QList urls; + urls.push_back(link); + RSLinkClipboard::copyLinks(urls); + } + } +#endif + + { + RetroShareLink link; + if (link.createForum(mCurrForumId, mCurrThreadId)) + { + QList urls; + urls.push_back(link); + RSLinkClipboard::copyLinks(urls); + } + } +} + +//#define DISABLE_OTHERCLASSES 1 + +void ForumsV2Dialog::newforum() +{ +#ifndef DISABLE_OTHERCLASSES + CreateForumV2 cf (this); + cf.exec (); +#endif +} + +void ForumsV2Dialog::createmessage() +{ + if (mCurrForumId.empty () || !IS_FORUM_SUBSCRIBED(subscribeFlags)) { + return; + } + +#ifndef DISABLE_OTHERCLASSES + CreateForumV2Msg *cfm = new CreateForumV2Msg(mCurrForumId, mCurrThreadId); + cfm->show(); +#endif + + /* window will destroy itself! */ +} + +void ForumsV2Dialog::createthread() +{ + if (mCurrForumId.empty ()) { + QMessageBox::information(this, tr("RetroShare"), tr("No Forum Selected!")); + return; + } + +#ifndef DISABLE_OTHERCLASSES + CreateForumV2Msg *cfm = new CreateForumV2Msg(mCurrForumId, ""); + cfm->setWindowTitle(tr("Start New Thread")); + cfm->show(); +#endif + + /* window will destroy itself! */ +} + +void ForumsV2Dialog::subscribeToForum() +{ + forumSubscribe(true); +} + +void ForumsV2Dialog::unsubscribeToForum() +{ + forumSubscribe(false); +} + +void ForumsV2Dialog::forumSubscribe(bool subscribe) +{ + if (mCurrForumId.empty()) { + return; + } + + rsForumsV2->groupSubscribe(mCurrForumId, subscribe); +} + +void ForumsV2Dialog::showForumDetails() +{ + if (mCurrForumId.empty()) { + return; + } + +#ifndef DISABLE_OTHERCLASSES + ForumV2Details fui; + + fui.showDetails (mCurrForumId); + fui.exec (); +#endif +} + +void ForumsV2Dialog::editForumDetails() +{ + if (mCurrForumId.empty()) { + return; + } + +#ifndef DISABLE_OTHERCLASSES + EditForumV2Details editUi(mCurrForumId, this); + editUi.exec(); +#endif +} + +void ForumsV2Dialog::replytomessage() +{ + if (mCurrForumId.empty() || mCurrThreadId.empty()) { + QMessageBox::information(this, tr("RetroShare"),tr("You cant reply to a non-existant Message")); + return; + } + + + requestMsgData_ReplyMessage(mCurrThreadId); +} + +void ForumsV2Dialog::replyMessageData(const RsForumV2Msg &msg) +{ + if ((msg.mMeta.mGroupId != mCurrForumId) || (msg.mMeta.mMsgId != mCurrThreadId)) + { + std::cerr << "ForumsV2Dialog::replyMessageData() ERROR Message Ids have changed!"; + std::cerr << std::endl; + return; + } + + // NB: TODO REMOVE rsPeers references. + if (rsPeers->getPeerName(msg.mMeta.mAuthorId) !="") + { + MessageComposer *nMsgDialog = MessageComposer::newMsg(); + nMsgDialog->insertTitleText(QString::fromUtf8(msg.mMeta.mMsgName.c_str()), MessageComposer::REPLY); + + QTextDocument doc ; + doc.setHtml(QString::fromUtf8(msg.mMsg.c_str())) ; + + nMsgDialog->insertPastedText(doc.toPlainText()); + nMsgDialog->addRecipient(MessageComposer::TO, msg.mMeta.mAuthorId, false); + nMsgDialog->show(); + nMsgDialog->activateWindow(); + + /* window will destroy itself! */ + } + else + { + QMessageBox::information(this, tr("RetroShare"),tr("You cant reply to an Anonymous Author")); + } +} + +void ForumsV2Dialog::filterRegExpChanged() +{ +// QRegExp regExp(ui.filterPatternLineEdit->text(), Qt::CaseInsensitive , QRegExp::FixedString); +// proxyModel->setFilterRegExp(regExp); + + QString text = ui.filterPatternLineEdit->text(); + + if (text.isEmpty()) { + ui.clearButton->hide(); + } else { + ui.clearButton->show(); + } + + FilterItems(); +} + +/* clear Filter */ +void ForumsV2Dialog::clearFilter() +{ + ui.filterPatternLineEdit->clear(); + ui.filterPatternLineEdit->setFocus(); +} + +void ForumsV2Dialog::changedViewBox() +{ + if (m_bProcessSettings) { + return; + } + + // save index + Settings->setValueToGroup("ForumsV2Dialog", "viewBox", ui.viewBox->currentIndex()); + + insertThreads(); +} + +void ForumsV2Dialog::filterColumnChanged() +{ + if (m_bProcessSettings) { + return; + } + + int filterColumn = FilterColumnFromComboBox(ui.filterColumnComboBox->currentIndex()); + if (filterColumn == COLUMN_THREAD_CONTENT) { + // need content ... refill + insertThreads(); + } else { + FilterItems(); + } + + // save index + Settings->setValueToGroup("ForumsV2Dialog", "filterColumn", filterColumn); +} + +void ForumsV2Dialog::FilterItems() +{ + QString sPattern = ui.filterPatternLineEdit->text(); + int filterColumn = FilterColumnFromComboBox(ui.filterColumnComboBox->currentIndex()); + + int nCount = ui.threadTreeWidget->topLevelItemCount (); + for (int nIndex = 0; nIndex < nCount; nIndex++) { + FilterItem(ui.threadTreeWidget->topLevelItem(nIndex), sPattern, filterColumn); + } +} + +void ForumsV2Dialog::shareKey() +{ + ShareKey shareUi(this, 0, mCurrForumId, FORUM_KEY_SHARE); + shareUi.exec(); +} + +bool ForumsV2Dialog::FilterItem(QTreeWidgetItem *pItem, QString &sPattern, int filterColumn) +{ + bool bVisible = true; + + if (sPattern.isEmpty() == false) { + if (pItem->text(filterColumn).contains(sPattern, Qt::CaseInsensitive) == false) { + bVisible = false; + } + } + + int nVisibleChildCount = 0; + int nCount = pItem->childCount(); + for (int nIndex = 0; nIndex < nCount; nIndex++) { + if (FilterItem(pItem->child(nIndex), sPattern, filterColumn)) { + nVisibleChildCount++; + } + } + + if (bVisible || nVisibleChildCount) { + pItem->setHidden(false); + } else { + pItem->setHidden(true); + } + + return (bVisible || nVisibleChildCount); +} + +void ForumsV2Dialog::updateMessageSummaryList(std::string forumId) +{ + QTreeWidgetItem *items[2] = { yourForums, subscribedForums }; + + for (int item = 0; item < 2; item++) { + int child; + int childCount = items[item]->childCount(); + for (child = 0; child < childCount; child++) { + QTreeWidgetItem *childItem = items[item]->child(child); + std::string childId = ui.forumTreeWidget->itemId(childItem).toStdString(); + if (childId.empty()) { + continue; + } + + if (forumId.empty() || childId == forumId) { + /* calculate unread messages */ + unsigned int newMessageCount = 0; + unsigned int unreadMessageCount = 0; + //rsForumsV2->getMessageCount(childId, newMessageCount, unreadMessageCount); + std::cerr << "IMPLEMENT rsForumsV2->getMessageCount()"; + std::cerr << std::endl; + + ui.forumTreeWidget->setUnreadCount(childItem, unreadMessageCount); + + if (forumId.empty() == false) { + /* Calculate only this forum */ + break; + } + } + } + } +} + +bool ForumsV2Dialog::navigate(const std::string& forumId, const std::string& msgId) +{ + if (forumId.empty()) { + return false; + } + + if (ui.forumTreeWidget->activateId(QString::fromStdString(forumId), msgId.empty()) == NULL) { + return false; + } + + /* Threads are filled in changedForum */ + if (mCurrForumId != forumId) { + return false; + } + + if (msgId.empty()) { + return true; + } + + if (mThreadLoading) { + mThreadLoad.FocusMsgId = msgId; + return true; + } + + /* Search exisiting item */ + QTreeWidgetItemIterator itemIterator(ui.threadTreeWidget); + QTreeWidgetItem *item = NULL; + while ((item = *itemIterator) != NULL) { + itemIterator++; + + if (item->data(COLUMN_THREAD_DATA, ROLE_THREAD_MSGID).toString().toStdString() == msgId) { + ui.threadTreeWidget->setCurrentItem(item); + ui.threadTreeWidget->setFocus(); + return true; + } + } + + return false; +} + +void ForumsV2Dialog::generateMassData() +{ +#ifdef DEBUG_FORUMS + if (mCurrForumId.empty ()) { + return; + } + + if (QMessageBox::question(this, "Generate mass data", "Do you really want to generate mass data ?", QMessageBox::Yes|QMessageBox::No, QMessageBox::No) == QMessageBox::No) { + return; + } + + for (int thread = 1; thread < 1000; thread++) { + ForumMsgInfo threadInfo; + threadInfo.forumId = mCurrForumId; + threadInfo.title = QString("Test %1").arg(thread, 3, 10, QChar('0')).toStdWString(); + threadInfo.msg = QString("That is only a test").toStdWString(); + + if (rsForumsV2->ForumMessageSend(threadInfo) == false) { + return; + } + + for (int msg = 1; msg < 3; msg++) { + ForumMsgInfo msgInfo; + msgInfo.forumId = mCurrForumId; + msgInfo.threadId = threadInfo.msgId; + msgInfo.parentId = threadInfo.msgId; + msgInfo.title = threadInfo.title; + msgInfo.msg = threadInfo.msg; + + if (rsForumsV2->ForumMessageSend(msgInfo) == false) { + return; + } + } + } +#endif +} + + + +/*********************** **** **** **** ***********************/ +/** Request / Response of Data ********************************/ +/*********************** **** **** **** ***********************/ + +#define FORUMSV2DIALOG_LISTING 1 +#define FORUMSV2DIALOG_CURRENTFORUM 2 +#define FORUMSV2DIALOG_INSERTTHREADS 3 +#define FORUMSV2DIALOG_INSERTCHILD 4 +#define FORUMV2DIALOG_INSERT_POST 5 +#define FORUMV2DIALOG_REPLY_MESSAGE 6 + + +void ForumsV2Dialog::insertForums() +{ + requestGroupSummary(); +} + +void ForumsV2Dialog::requestGroupSummary() +{ + std::cerr << "ForumsV2Dialog::requestGroupSummary()"; + std::cerr << std::endl; + + std::list ids; + RsTokReqOptions opts; + uint32_t token; + mForumQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, ids, FORUMSV2DIALOG_LISTING); +} + +void ForumsV2Dialog::loadGroupSummary(const uint32_t &token) +{ + std::cerr << "ForumsV2Dialog::loadGroupSummary()"; + std::cerr << std::endl; + + std::list groupInfo; + rsForumsV2->getGroupSummary(token, groupInfo); + + if (groupInfo.size() > 0) + { + insertForumsData(groupInfo); + } + else + { + std::cerr << "ForumsV2Dialog::loadGroupSummary() ERROR No Groups..."; + std::cerr << std::endl; + } +} + +/*********************** **** **** **** ***********************/ +/*********************** **** **** **** ***********************/ + + + +void ForumsV2Dialog::requestGroupSummary_CurrentForum(const std::string &forumId) +{ + RsTokReqOptions opts; + + std::list grpIds; + grpIds.push_back(forumId); + + uint32_t token; + mForumQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, grpIds, FORUMSV2DIALOG_CURRENTFORUM); +} + +void ForumsV2Dialog::loadGroupSummary_CurrentForum(const uint32_t &token) +{ + std::cerr << "ForumsV2Dialog::loadGroupSummary_CurrentForum()"; + std::cerr << std::endl; + + std::list groupInfo; + rsForumsV2->getGroupSummary(token, groupInfo); + + if (groupInfo.size() == 1) + { + RsGroupMetaData fi = groupInfo.front(); + insertForumThreads(fi); + } + else + { + std::cerr << "ForumsV2Dialog::loadGroupSummary_CurrentForum() ERROR Invalid Number of Groups..."; + std::cerr << std::endl; + } +} + +/*********************** **** **** **** ***********************/ +/*********************** **** **** **** ***********************/ +/*********************** **** **** **** ***********************/ +/*********************** **** **** **** ***********************/ + + + +void ForumsV2Dialog::loadCurrentForumThreads(const std::string &forumId) +{ + /* if already active -> kill current loading */ + if (mThreadLoading) + { + /* Cleanup */ + + /* Wipe Widget Tree */ + mThreadLoad.Items.clear(); + + /* Stop all active requests */ + std::map::iterator it; + for(it = mThreadLoad.MsgTokens.begin(); it != mThreadLoad.MsgTokens.end(); it++) + { + mForumQueue->cancelRequest(it->first); + } + + mThreadLoad.MsgTokens.clear(); + mThreadLoad.ItemToExpand.clear(); + } + + /* initiate loading */ + mThreadLoading = true; + + mThreadLoad.ForumId = mCurrForumId; + mThreadLoad.FilterColumn = FilterColumnFromComboBox(ui.filterColumnComboBox->currentIndex()); + mThreadLoad.ViewType = ui.viewBox->currentIndex(); + mThreadLoad.FillComplete = false; + + if (lastViewType != mThreadLoad.ViewType || lastForumID != mCurrForumId) { + mThreadLoad.FillComplete = true; + } + + mThreadLoad.FlatView = false; + mThreadLoad.UseChildTS = false; + mThreadLoad.ExpandNewMessages = Settings->getExpandNewMessages(); + mThreadLoad.SubscribeFlags = subscribeFlags; + + if (mThreadLoad.ViewType == VIEW_FLAT) { + ui.threadTreeWidget->setRootIsDecorated(false); + } else { + ui.threadTreeWidget->setRootIsDecorated(true); + } + + switch(mThreadLoad.ViewType) + { + case VIEW_LAST_POST: + mThreadLoad.UseChildTS = true; + break; + case VIEW_FLAT: + mThreadLoad.FlatView = true; + break; + case VIEW_THREADED: + break; + } + + requestGroupThreadData_InsertThreads(forumId); +} + + + +void ForumsV2Dialog::requestGroupThreadData_InsertThreads(const std::string &forumId) +{ + RsTokReqOptions opts; + + opts.mOptions = RS_TOKREQOPT_MSG_THREAD | RS_TOKREQOPT_MSG_LATEST; + + std::list grpIds; + grpIds.push_back(forumId); + + uint32_t token; + mForumQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, grpIds, FORUMSV2DIALOG_INSERTTHREADS); +} + + +void ForumsV2Dialog::loadGroupThreadData_InsertThreads(const uint32_t &token) +{ + std::cerr << "ForumsV2Dialog::loadGroupThreadData_InsertThreads()"; + std::cerr << std::endl; + + bool moreData = true; + while(moreData) + { + RsForumV2Msg msg; + if (rsForumsV2->getMsgData(token, msg)) + { + std::cerr << "ForumsV2Dialog::loadGroupThreadData_InsertThreads() MsgId: " << msg.mMeta.mMsgId; + std::cerr << std::endl; + + loadForumBaseThread(msg); + } + else + { + moreData = false; + } + } +} + +bool ForumsV2Dialog::convertMsgToThreadWidget(const RsForumV2Msg &msgInfo, std::string authorName, + bool useChildTS, uint32_t filterColumn, QTreeWidgetItem *item) +{ + QString text; + + { + QDateTime qtime; + if (useChildTS) + qtime.setTime_t(msgInfo.mMeta.mChildTs); + else + qtime.setTime_t(msgInfo.mMeta.mPublishTs); + + text = qtime.toString("yyyy-MM-dd hh:mm:ss"); + if (useChildTS) + { + QDateTime qtime2; + qtime2.setTime_t(msgInfo.mMeta.mPublishTs); + QString timestamp2 = qtime2.toString("yyyy-MM-dd hh:mm:ss"); + text += " / "; + text += timestamp2; + } + item->setText(COLUMN_THREAD_DATE, text); + } + + item->setText(COLUMN_THREAD_TITLE, QString::fromUtf8(msgInfo.mMeta.mMsgName.c_str())); + + text = QString::fromUtf8(authorName.c_str()); + if (text.isEmpty()) + { + item->setText(COLUMN_THREAD_AUTHOR, tr("Anonymous")); + } + else + { + item->setText(COLUMN_THREAD_AUTHOR, text); + } + + if (msgInfo.mMeta.mMsgFlags & RS_DISTRIB_AUTHEN_REQ) + { + item->setText(COLUMN_THREAD_SIGNED, tr("signed")); + item->setIcon(COLUMN_THREAD_SIGNED, QIcon(":/images/mail-signed.png")); + } + else + { + item->setText(COLUMN_THREAD_SIGNED, tr("none")); + item->setIcon(COLUMN_THREAD_SIGNED, QIcon(":/images/mail-signature-unknown.png")); + } + + if (filterColumn == COLUMN_THREAD_CONTENT) { + // need content for filter + QTextDocument doc; + doc.setHtml(QString::fromUtf8(msgInfo.mMsg.c_str())); + item->setText(COLUMN_THREAD_CONTENT, doc.toPlainText().replace(QString("\n"), QString(" "))); + } + + item->setData(COLUMN_THREAD_DATA, ROLE_THREAD_MSGID, QString::fromStdString(msgInfo.mMeta.mMsgId)); + +#if 0 + if (IS_FORUM_SUBSCRIBED(subscribeFlags) && !(msginfo.mMsgFlags & RS_DISTRIB_MISSING_MSG)) { + rsForumsV2->getMessageStatus(msginfo.forumId, msginfo.msgId, status); + } else { + // show message as read + status = RSGXS_MSG_STATUS_READ; + } +#endif + item->setData(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS, msgInfo.mMeta.mMsgStatus); + + item->setData(COLUMN_THREAD_DATA, ROLE_THREAD_MISSING, (msgInfo.mMeta.mMsgFlags & RS_DISTRIB_MISSING_MSG) ? true : false); + + return true; +} + + +void ForumsV2Dialog::loadForumBaseThread(const RsForumV2Msg &msg) +{ + std::string authorName = rsPeers->getPeerName(msg.mMeta.mAuthorId); + + QTreeWidgetItem *item = new QTreeWidgetItem(); // no Parent. + + convertMsgToThreadWidget(msg, authorName, mThreadLoad.UseChildTS, mThreadLoad.FilterColumn, item); + + /* request Children Data */ + uint32_t token; + requestChildData_InsertThreads(token, msg.mMeta.mMsgId); + + /* store pair of (token, item) */ + mThreadLoad.MsgTokens[token] = item; + + /* add item to final tree */ + mThreadLoad.Items.append(item); +} + + + +/*********************** **** **** **** ***********************/ + +void ForumsV2Dialog::requestChildData_InsertThreads(uint32_t &token, const std::string &parentId) +{ + RsTokReqOptions opts; + + opts.mOptions = RS_TOKREQOPT_MSG_PARENT | RS_TOKREQOPT_MSG_LATEST; + + std::list msgIds; + msgIds.push_back(parentId); + + mForumQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, FORUMSV2DIALOG_INSERTCHILD); +} + + +void ForumsV2Dialog::loadChildData_InsertThreads(const uint32_t &token) +{ + std::cerr << "ForumsV2Dialog::loadChildData_InsertThreads()"; + std::cerr << std::endl; + + /* find the matching *item */ + std::map::iterator it; + it = mThreadLoad.MsgTokens.find(token); + if (it == mThreadLoad.MsgTokens.end()) + { + std::cerr << "ForumsV2Dialog::loadGroupThreadData_InsertThreads() ERROR Missing Token->Parent in Map"; + std::cerr << std::endl; + /* finished with this one */ + return; + } + + QTreeWidgetItem *parent = it->second; + // cleanup map. + mThreadLoad.MsgTokens.erase(it); + + std::cerr << "ForumsV2Dialog::loadGroupThreadData_InsertThreads()"; + std::cerr << std::endl; + + bool moreData = true; + while(moreData) + { + RsForumV2Msg msg; + if (rsForumsV2->getMsgData(token, msg)) + { + std::cerr << "ForumsV2Dialog::loadGroupThreadData_InsertThreads() MsgId: " << msg.mMeta.mMsgId; + std::cerr << std::endl; + + loadForumChildMsg(msg, parent); + } + else + { + moreData = false; + } + } + + + /* check for completion */ + if (mThreadLoad.MsgTokens.size() == 0) + { + /* finished */ + /* push data into GUI */ + fillThreadFinished(); + } +} + + +void ForumsV2Dialog::loadForumChildMsg(const RsForumV2Msg &msg, QTreeWidgetItem *parent) +{ + std::string authorName = rsPeers->getPeerName(msg.mMeta.mAuthorId); + + QTreeWidgetItem *child = NULL; + + if (mThreadLoad.FlatView) + { + child = new QTreeWidgetItem(NULL); // no Parent. + } + else + { + child = new QTreeWidgetItem(parent); + } + + + convertMsgToThreadWidget(msg, authorName, mThreadLoad.UseChildTS, mThreadLoad.FilterColumn, child); + + /* request Children Data */ + uint32_t token; + requestChildData_InsertThreads(token, msg.mMeta.mMsgId); + + /* store pair of (token, item) */ + mThreadLoad.MsgTokens[token] = child; + + // Leave this here... BUT IT WILL NEED TO BE FIXED. + if (mThreadLoad.FillComplete && mThreadLoad.ExpandNewMessages && IS_UNREAD(msg.mMeta.mMsgStatus)) + { + QTreeWidgetItem *pParent = child; + while ((pParent = pParent->parent()) != NULL) + { + if (std::find(mThreadLoad.ItemToExpand.begin(), mThreadLoad.ItemToExpand.end(), pParent) == mThreadLoad.ItemToExpand.end()) + { + mThreadLoad.ItemToExpand.push_back(pParent); + } + } + } + + if (mThreadLoad.FlatView) + { + /* add item to final tree */ + mThreadLoad.Items.append(child); + } +} + + + +/*********************** **** **** **** ***********************/ +/*********************** **** **** **** ***********************/ + +void ForumsV2Dialog::requestMsgData_InsertPost(const std::string &msgId) +{ + RsTokReqOptions opts; + + std::list msgIds; + msgIds.push_back(msgId); + + uint32_t token; + mForumQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, FORUMV2DIALOG_INSERT_POST); +} + + +void ForumsV2Dialog::loadMsgData_InsertPost(const uint32_t &token) +{ + std::cerr << "ForumsV2Dialog::loadMsgData_InsertPost()"; + std::cerr << std::endl; + + RsForumV2Msg msg; + if (rsForumsV2->getMsgData(token, msg)) + { + insertPostData(msg); + } + else + { + std::cerr << "ForumsV2Dialog::loadMsgData_InsertPost() ERROR Missing Message Data..."; + std::cerr << std::endl; + } +} + + +/*********************** **** **** **** ***********************/ +/*********************** **** **** **** ***********************/ + +void ForumsV2Dialog::requestMsgData_ReplyMessage(const std::string &msgId) +{ + RsTokReqOptions opts; + + std::list msgIds; + msgIds.push_back(msgId); + + uint32_t token; + mForumQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, FORUMV2DIALOG_REPLY_MESSAGE); +} + + +void ForumsV2Dialog::loadMsgData_ReplyMessage(const uint32_t &token) +{ + std::cerr << "ForumsV2Dialog::loadMsgData_ReplyMessage()"; + std::cerr << std::endl; + + RsForumV2Msg msg; + if (rsForumsV2->getMsgData(token, msg)) + { + replyMessageData(msg); + } + else + { + std::cerr << "ForumsV2Dialog::loadMsgData_ReplyMessage() ERROR Missing Message Data..."; + std::cerr << std::endl; + } +} + + +/*********************** **** **** **** ***********************/ +/*********************** **** **** **** ***********************/ + + + +/*********************** **** **** **** ***********************/ +/*********************** **** **** **** ***********************/ +/*********************** **** **** **** ***********************/ +/*********************** **** **** **** ***********************/ + +void ForumsV2Dialog::loadRequest(const TokenQueue *queue, const TokenRequest &req) +{ + std::cerr << "ForumsV2Dialog::loadRequest() UserType: " << req.mUserType; + std::cerr << std::endl; + + if (queue == mForumQueue) + { + /* now switch on req */ + switch(req.mUserType) + { + case FORUMSV2DIALOG_LISTING: + loadGroupSummary(req.mToken); + break; + + case FORUMSV2DIALOG_CURRENTFORUM: + loadGroupSummary_CurrentForum(req.mToken); + break; + + case FORUMSV2DIALOG_INSERTTHREADS: + loadGroupThreadData_InsertThreads(req.mToken); + break; + + case FORUMSV2DIALOG_INSERTCHILD: + loadChildData_InsertThreads(req.mToken); + break; + + case FORUMV2DIALOG_INSERT_POST: + loadMsgData_InsertPost(req.mToken); + break; + + case FORUMV2DIALOG_REPLY_MESSAGE: + loadMsgData_ReplyMessage(req.mToken); + break; + + default: + std::cerr << "ForumsV2Dialog::loadRequest() ERROR: INVALID TYPE"; + std::cerr << std::endl; + break; + } + } +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/retroshare-gui/src/gui/ForumsV2Dialog.h b/retroshare-gui/src/gui/ForumsV2Dialog.h new file mode 100644 index 000000000..0478c2bea --- /dev/null +++ b/retroshare-gui/src/gui/ForumsV2Dialog.h @@ -0,0 +1,265 @@ +/**************************************************************** + * 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 _FORUMSV2DIALOG_H +#define _FORUMSV2DIALOG_H + +#include + +#include "mainpage.h" +#include "RsAutoUpdatePage.h" +#include "ui_ForumsV2Dialog.h" + +#include + +#include "util/TokenQueue.h" + +#include + +class ForumInfo; + + +/* These are all the parameters that are required for thread loading. + * They are kept static for the load duration. + */ + +class ForumsV2ThreadLoadParameters +{ + public: + + std::string ForumId; + std::string FocusMsgId; + + uint32_t SubscribeFlags; + int ViewType; + uint32_t FilterColumn; + + std::map MsgTokens; + QList Items; + QList ItemToExpand; + + bool FillComplete; + bool FlatView; + bool UseChildTS; + bool ExpandNewMessages; +}; + + + + + + +class ForumsV2Dialog : public RsAutoUpdatePage, public TokenResponse +{ + Q_OBJECT + +public: + ForumsV2Dialog(QWidget *parent = 0); + ~ForumsV2Dialog(); + + bool navigate(const std::string& forumId, const std::string& msgId); + + /* overloaded from RsAuthUpdatePage */ + virtual void updateDisplay(); + +protected: + bool eventFilter(QObject *obj, QEvent *ev); + +private slots: + /** Create the context popup menu and it's submenus */ + void forumListCustomPopupMenu( QPoint point ); + void threadListCustomPopupMenu( QPoint point ); + void restoreForumKeys(); + void newforum(); + + void changedForum(const QString &id); + void changedThread(); + void clickedThread (QTreeWidgetItem *item, int column); + + void replytomessage(); + void replyMessageData(const RsForumV2Msg &msg); + + //void print(); + //void printpreview(); + + //void removemessage(); + void markMsgAsRead(); + void markMsgAsReadChildren(); + void markMsgAsReadAll(); + void markMsgAsUnread(); + void markMsgAsUnreadAll(); + void markMsgAsUnreadChildren(); + void copyForumLink(); + void copyMessageLink(); + + /* handle splitter */ + void togglethreadview(); + + void createthread(); + void createmessage(); + + void subscribeToForum(); + void unsubscribeToForum(); + + void showForumDetails(); + void editForumDetails(); + + void previousMessage (); + void nextMessage (); + void nextUnreadMessage(); + void downloadAllFiles(); + + void changedViewBox(); + + void filterColumnChanged(); + void filterRegExpChanged(); + void clearFilter(); + + void generateMassData(); + + void fillThreadFinished(); + void fillThreadProgress(int current, int count); + + void shareKey(); + +private: + void insertForums(); + void insertThreads(); + void insertPost(); + void insertPostData(const RsForumV2Msg &msg); // Second Half. + + void updateMessageSummaryList(std::string forumId); + //void forumInfoToGroupItemInfo(const ForumInfo &forumInfo, GroupItemInfo &groupItemInfo); + void forumInfoToGroupItemInfo(const RsGroupMetaData &forumInfo, GroupItemInfo &groupItemInfo); + + void forumSubscribe(bool subscribe); + void FillThreads(QList &ThreadList, bool bExpandNewMessages, QList &itemToExpand); + void FillChildren(QTreeWidgetItem *Parent, QTreeWidgetItem *NewParent, bool bExpandNewMessages, QList &itemToExpand); + + int getSelectedMsgCount(QList *pRows, QList *pRowsRead, QList *pRowsUnread); + void setMsgAsReadUnread(QList &Rows, bool bRead); + void markMsgAsReadUnread(bool bRead, bool bChildren, bool bForum); + void CalculateIconsAndFonts(QTreeWidgetItem *pItem = NULL); + void CalculateIconsAndFonts(QTreeWidgetItem *pItem, bool &bHasReadChilddren, bool &bHasUnreadChilddren); + + void processSettings(bool bLoad); + void togglethreadview_internal(); + + void FilterItems(); + bool FilterItem(QTreeWidgetItem *pItem, QString &sPattern, int filterColumn); + + + // New Request/Response Loading Functions. + void insertForumsData(const std::list &forumList); + void insertForumThreads(const RsGroupMetaData &fi); + + void requestGroupSummary(); + void loadGroupSummary(const uint32_t &token); + + void requestGroupSummary_CurrentForum(const std::string &forumId); + void loadGroupSummary_CurrentForum(const uint32_t &token); + + void loadCurrentForumThreads(const std::string &forumId); + void requestGroupThreadData_InsertThreads(const std::string &forumId); + void loadGroupThreadData_InsertThreads(const uint32_t &token); + void loadForumBaseThread(const RsForumV2Msg &msg); + + void requestChildData_InsertThreads(uint32_t &token, const std::string &parentId); + void loadChildData_InsertThreads(const uint32_t &token); + void loadForumChildMsg(const RsForumV2Msg &msg, QTreeWidgetItem *parent); + + void requestMsgData_InsertPost(const std::string &msgId); + void loadMsgData_InsertPost(const uint32_t &token); + void requestMsgData_ReplyMessage(const std::string &msgId); + void loadMsgData_ReplyMessage(const uint32_t &token); + + bool convertMsgToThreadWidget(const RsForumV2Msg &msgInfo, std::string authorName, + bool useChildTS, uint32_t filterColumn, QTreeWidgetItem *item); + + // Callback for all Loads. + void loadRequest(const TokenQueue *queue, const TokenRequest &req); + + TokenQueue *mForumQueue; + + + bool m_bProcessSettings; + + QTreeWidgetItem *yourForums; + QTreeWidgetItem *subscribedForums; + QTreeWidgetItem *popularForums; + QTreeWidgetItem *otherForums; + + std::string mCurrForumId; + std::string mCurrThreadId; + int subscribeFlags; + + QFont m_ForumNameFont; + int lastViewType; + std::string lastForumID; + + //ForumsV2FillThread *fillThread; + + // New Datatypes to replace the FillThread. + bool mThreadLoading; + ForumsV2ThreadLoadParameters mThreadLoad; + + + /** Qt Designer generated object */ + Ui::ForumsV2Dialog ui; +}; + +#if 0 +class ForumsV2FillThread : public QThread +{ + Q_OBJECT + +public: + ForumsV2FillThread(ForumsV2Dialog *parent); + ~ForumsV2FillThread(); + + void run(); + void stop(); + bool wasStopped() { return stopped; } + +signals: + void progress(int current, int count); + +public: + std::string forumId; + int filterColumn; + int subscribeFlags; + bool fillComplete; + int viewType; + bool expandNewMessages; + std::string focusMsgId; + + QList Items; + QList ItemToExpand; + +private: + volatile bool stopped; +}; + +#endif + + +#endif + diff --git a/retroshare-gui/src/gui/ForumsV2Dialog.ui b/retroshare-gui/src/gui/ForumsV2Dialog.ui new file mode 100644 index 000000000..059e184ef --- /dev/null +++ b/retroshare-gui/src/gui/ForumsV2Dialog.ui @@ -0,0 +1,1299 @@ + + + ForumsV2Dialog + + + + 0 + 0 + 732 + 420 + + + + + 0 + 2 + + + + + 60 + 0 + + + + + + + + + 0 + 0 + 0 + + + + + + + 208 + 208 + 208 + + + + + + + 255 + 255 + 255 + + + + + + + 247 + 247 + 247 + + + + + + + 104 + 104 + 104 + + + + + + + 139 + 139 + 139 + + + + + + + 0 + 0 + 0 + + + + + + + 255 + 255 + 255 + + + + + + + 0 + 0 + 0 + + + + + + + 255 + 255 + 255 + + + + + + + 240 + 240 + 240 + + + + + + + 0 + 0 + 0 + + + + + + + 0 + 0 + 128 + + + + + + + 255 + 255 + 255 + + + + + + + 0 + 0 + 255 + + + + + + + 255 + 0 + 255 + + + + + + + 231 + 231 + 231 + + + + + + + + + 0 + 0 + 0 + + + + + + + 208 + 208 + 208 + + + + + + + 255 + 255 + 255 + + + + + + + 247 + 247 + 247 + + + + + + + 104 + 104 + 104 + + + + + + + 139 + 139 + 139 + + + + + + + 0 + 0 + 0 + + + + + + + 255 + 255 + 255 + + + + + + + 0 + 0 + 0 + + + + + + + 255 + 255 + 255 + + + + + + + 240 + 240 + 240 + + + + + + + 0 + 0 + 0 + + + + + + + 192 + 192 + 192 + + + + + + + 0 + 0 + 0 + + + + + + + 0 + 0 + 255 + + + + + + + 255 + 0 + 255 + + + + + + + 231 + 231 + 231 + + + + + + + + + 104 + 104 + 104 + + + + + + + 208 + 208 + 208 + + + + + + + 255 + 255 + 255 + + + + + + + 247 + 247 + 247 + + + + + + + 104 + 104 + 104 + + + + + + + 139 + 139 + 139 + + + + + + + 104 + 104 + 104 + + + + + + + 255 + 255 + 255 + + + + + + + 104 + 104 + 104 + + + + + + + 240 + 240 + 240 + + + + + + + 240 + 240 + 240 + + + + + + + 0 + 0 + 0 + + + + + + + 0 + 0 + 128 + + + + + + + 255 + 255 + 255 + + + + + + + 0 + 0 + 255 + + + + + + + 255 + 0 + 255 + + + + + + + 231 + 231 + 231 + + + + + + + + + Arial + 8 + 50 + false + false + false + false + + + + Qt::DefaultContextMenu + + + + 9 + + + 9 + + + + + Qt::Horizontal + + + + + 300 + 300 + + + + QFrame#frame{border: none;} + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 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/konversation.png + + + true + + + + + + + + Arial + 10 + + + + <!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:10pt; 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-weight:600;">Forums</span></p></body></html> + + + + + + + + + Qt::Horizontal + + + + 123 + 13 + + + + + + + + Qt::NoFocus + + + Display + + + 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/looknfeel.png:/images/looknfeel.png + + + true + + + + + + + Qt::NoFocus + + + Create Forum + + + + :/images/new_forum16.png:/images/new_forum16.png + + + true + + + + + + + + + + + 0 + 0 + + + + + 9 + + + + + -1 + -1 + + + + + + + + + Qt::Vertical + + + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + + 10 + 75 + true + + + + Forum: + + + + + + + + 2 + 0 + + + + + 0 + 0 + + + + + 16777215 + 1677215 + + + + +border: 2px solid #CCCCCC; +border-radius:6px; +background: white; + + + + + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + + + + + + + + Last Post + + + + + Threaded View + + + + + Flat View + + + + + + + + + + + 9 + + + + Qt::CustomContextMenu + + + true + + + true + + + + Title + + + + + + + + + :/images/message-state-header.png:/images/message-state-header.png + + + + + Date + + + + + Author + + + + + Signed + + + + + + + + + + + 0 + 0 + + + + + 10 + 75 + true + + + + Thread: + + + + + + + QLabel#threadTitle{ +border: 2px solid #CCCCCC; +border-radius: 6px; +background: white;} + + + true + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + + + + + + + false + + + + 0 + 0 + + + + + 24 + 24 + + + + + 24 + 24 + + + + Qt::NoFocus + + + Previous Thread + + + + + + + :/images/back.png:/images/back.png + + + + + + + false + + + + 0 + 0 + + + + + 24 + 24 + + + + + 24 + 24 + + + + Qt::NoFocus + + + Next Thread + + + + + + + :/images/forward.png:/images/forward.png + + + + + + + + 24 + 24 + + + + Qt::NoFocus + + + + + + + :/images/edit_remove24.png:/images/edit_remove24.png + + + true + + + true + + + + + + + + 24 + 24 + + + + Qt::NoFocus + + + Download all files + + + + :/images/down.png:/images/down.png + + + + + + + + 0 + 0 + + + + Next unread + + + + + + + + + + 0 + 32 + + + + QFrame#frame_2{ +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 + + + + + 2 + + + + + + + + :/images/find-16.png + + + + + + + <!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-size:8pt;">Search forums</span></p></body></html> + + + + + + + + 16 + 16 + + + + + 16 + 16 + + + + + MS Shell Dlg 2 + + + + Qt::NoFocus + + + Reset + + + QPushButton +{ + border-image: url(:/images/closenormal.png) +} + +QPushButton:hover +{ +border-image: url(:/images/closehover.png) +} + +QPushButton:pressed { +border-image: url(:/images/closepressed.png) +} + + + + + + + + + + + + + 0 + 0 + + + + + MS Shell Dlg 2 + + + + 1 + + + + Date + + + + + Title + + + + + Author + + + + + Content + + + + + + + + + 24 + 24 + + + + Qt::NoFocus + + + Reply Message + + + + :/images/mail_reply.png:/images/mail_reply.png + + + true + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 40 + 20 + + + + + + + + + 24 + 24 + + + + Qt::NoFocus + + + Start new Thread for Selected Forum + + + + :/images/mail_new.png:/images/mail_new.png + + + true + + + + + + + + + + + + + 10 + 75 + true + + + + Loading + + + + + + + + 16777215 + 25 + + + + 1000 + + + 0 + + + false + + + + + + + + + + + 0 + 10 + + + + + 9 + + + + true + + + true + + + + + + + + + Print + + + + + PrintPreview + + + + + + GroupTreeWidget + QWidget +
gui/common/GroupTreeWidget.h
+ 1 +
+
+ + + + +
diff --git a/retroshare-gui/src/gui/Identity/IdDialog.cpp b/retroshare-gui/src/gui/Identity/IdDialog.cpp index 7b2939641..23e946f4f 100644 --- a/retroshare-gui/src/gui/Identity/IdDialog.cpp +++ b/retroshare-gui/src/gui/Identity/IdDialog.cpp @@ -35,6 +35,9 @@ * #define ID_DEBUG 1 *****/ +// Data Requests. +#define IDDIALOG_IDLIST 1 +#define IDDIALOG_IDDETAILS 2 /**************************************************************** */ @@ -76,7 +79,9 @@ IdDialog::IdDialog(QWidget *parent) timer->start(1000); rsIdentity->generateDummyData(); - mWaitingForRequest = false; + + mIdQueue = new TokenQueue(rsIdentity, this); + } void IdDialog::ListTypeToggled(bool checked) @@ -123,24 +128,25 @@ void IdDialog::blankSelection() } + + void IdDialog::requestIdDetails(std::string &id) { + RsTokReqOptions opts; + uint32_t token; + std::list groupIds; + groupIds.push_back(id); - std::list ids; - ids.push_back(id); - - rsIdentity->requestIdentities(token, ids); - lockForRequest(token, RSID_REQ_IDDETAILS); - + mIdQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, groupIds, IDDIALOG_IDDETAILS); } void IdDialog::insertIdDetails(uint32_t token) { /* get details from libretroshare */ - RsIdData data; - if (!rsIdentity->getIdentity(token, data)) + RsIdGroup data; + if (!rsIdentity->getGroupData(token, data)) { ui.lineEdit_KeyId->setText("ERROR GETTING KEY!"); return; @@ -151,8 +157,10 @@ void IdDialog::insertIdDetails(uint32_t token) RsPeerDetails details; rsPeers->getPeerDetails(gpgid, details); - ui.lineEdit_Nickname->setText(QString::fromStdString(data.mNickname)); - ui.lineEdit_KeyId->setText(QString::fromStdString(data.mKeyId)); + //ui.lineEdit_Nickname->setText(QString::fromStdString(data.mNickname)); + ui.lineEdit_Nickname->setText(QString::fromStdString(data.mMeta.mGroupName)); + //ui.lineEdit_KeyId->setText(QString::fromStdString(data.mKeyId)); + ui.lineEdit_KeyId->setText(QString::fromStdString(data.mMeta.mGroupId)); ui.lineEdit_GpgHash->setText(QString::fromStdString(data.mGpgIdHash)); ui.lineEdit_GpgId->setText(QString::fromStdString(data.mGpgId)); ui.lineEdit_GpgName->setText(QString::fromStdString(data.mGpgName)); @@ -200,8 +208,6 @@ void IdDialog::checkUpdate() if (!rsIdentity) return; - checkForRequest(); - if (rsIdentity->updated()) { requestIdList(); @@ -243,57 +249,25 @@ void IdDialog::OpenOrShowEditDialog() } std::string keyId = item->text(RSID_COL_KEYID).toStdString(); - requestIdEdit(keyId); -} - -void IdDialog::requestIdEdit(std::string &id) -{ - uint32_t token; - - std::list ids; - ids.push_back(id); - - rsIdentity->requestIdentities(token, ids); - lockForRequest(token, RSID_REQ_IDEDIT); - -} - - -void IdDialog::showIdEdit(uint32_t token) -{ if (mEditDialog) { - mEditDialog->setupExistingId(token); - + mEditDialog->setupExistingId(keyId); mEditDialog->show(); } } - - void IdDialog::requestIdList() { + RsTokReqOptions opts; + uint32_t token; + std::list groupIds; - rsIdentity->requestIdentityList(token); - - lockForRequest(token, RSID_REQ_IDLIST); + mIdQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, groupIds, IDDIALOG_IDLIST); } -void IdDialog::requestIdData(std::list &ids) -{ - uint32_t token; - - rsIdentity->requestIdentities(token, ids); - - lockForRequest(token, RSID_REQ_IDLISTDATA); -} - - - - void IdDialog::insertIdList(uint32_t token) { QTreeWidget *tree = ui.treeWidget_IdList; @@ -313,8 +287,8 @@ void IdDialog::insertIdList(uint32_t token) //for(it = ids.begin(); it != ids.end(); it++) //{ - RsIdData data; - while(rsIdentity->getIdentity(token, data)) + RsIdGroup data; + while(rsIdentity->getGroupData(token, data)) { /* do filtering */ @@ -367,8 +341,10 @@ void IdDialog::insertIdList(uint32_t token) QTreeWidgetItem *item = new QTreeWidgetItem(NULL); - item->setText(RSID_COL_NICKNAME, QString::fromStdString(data.mNickname)); - item->setText(RSID_COL_KEYID, QString::fromStdString(data.mKeyId)); + //item->setText(RSID_COL_NICKNAME, QString::fromStdString(data.mNickname)); + //item->setText(RSID_COL_KEYID, QString::fromStdString(data.mKeyId)); + item->setText(RSID_COL_NICKNAME, QString::fromStdString(data.mMeta.mGroupName)); + item->setText(RSID_COL_KEYID, QString::fromStdString(data.mMeta.mGroupId)); item->setText(RSID_COL_IDTYPE, QString::fromStdString(rsIdTypeToString(data.mIdType))); tree->addTopLevelItem(item); @@ -378,102 +354,29 @@ void IdDialog::insertIdList(uint32_t token) updateSelection(); } - - - -void IdDialog::lockForRequest(uint32_t token, uint32_t reqtype) +void IdDialog::loadRequest(const TokenQueue *queue, const TokenRequest &req) { - - /* store token for later results retrival */ - if (mWaitingForRequest) + std::cerr << "IdDialog::loadRequest() UserType: " << req.mUserType; + std::cerr << std::endl; + + switch(req.mUserType) { - std::cerr << "IdDialog::lockForRequest() LOCKED ALREADY - BIG ERROR"; - std::cerr << std::endl; - } - - mWaitingForRequest = true; - mRequestToken = token; - mRequestType = reqtype; - - std::cerr << "IdDialog::lockForRequest() Token: " << token << " ReqType: " << reqtype; - std::cerr << std::endl; - -} - - -void IdDialog::checkForRequest() -{ - - if (mWaitingForRequest) - { - /* check token */ - if (4 == rsIdentity->requestStatus(mRequestToken)) - loadRequest(); - } -} - - -void IdDialog::loadRequest() -{ - if (!mWaitingForRequest) - { - std::cerr << "IdDialog::loadRequest() NOT LOCKED - BIG ERROR"; - std::cerr << std::endl; - } - - /* unlock gui */ - mWaitingForRequest = false; - - - switch (mRequestType) - { - case RSID_REQ_IDLIST: - { - std::cerr << "IdDialog::loadRequest() RSID_REQ_IDLIST"; - std::cerr << std::endl; - - std::list ids; - rsIdentity->getIdentityList(mRequestToken, ids); - - /* request data - straight away */ - - requestIdData(ids); - } - break; - - case RSID_REQ_IDLISTDATA: - { - std::cerr << "IdDialog::loadRequest() RSID_REQ_IDLISTDATA"; - std::cerr << std::endl; - insertIdList(mRequestToken); - } - break; - - - case RSID_REQ_IDDETAILS: - { - std::cerr << "IdDialog::loadRequest() RSID_REQ_IDDETAILS"; - std::cerr << std::endl; - insertIdDetails(mRequestToken); - } - break; - - case RSID_REQ_IDEDIT: - { - std::cerr << "IdDialog::loadRequest() RSID_REQ_IDEDIT"; - std::cerr << std::endl; - showIdEdit(mRequestToken); - } - break; - + case IDDIALOG_IDLIST: + insertIdList(req.mToken); + break; + + case IDDIALOG_IDDETAILS: + insertIdDetails(req.mToken); + break; + default: - break; + std::cerr << "IdDialog::loadRequest() ERROR"; + std::cerr << std::endl; + break; + } } - - - - + diff --git a/retroshare-gui/src/gui/Identity/IdDialog.h b/retroshare-gui/src/gui/Identity/IdDialog.h index 8d2b8411c..24d618288 100644 --- a/retroshare-gui/src/gui/Identity/IdDialog.h +++ b/retroshare-gui/src/gui/Identity/IdDialog.h @@ -27,20 +27,22 @@ #include "gui/mainpage.h" #include "ui_IdDialog.h" -#include +#include #include #include "gui/Identity/IdEditDialog.h" -//#include "gui/TheWire/PulseAddDialog.h" +#include "util/TokenQueue.h" -class IdDialog : public MainPage +class IdDialog : public MainPage, public TokenResponse { Q_OBJECT public: IdDialog(QWidget *parent = 0); +void loadRequest(const TokenQueue *queue, const TokenRequest &req); + private slots: @@ -64,15 +66,9 @@ private: void requestIdEdit(std::string &id); void showIdEdit(uint32_t token); - void lockForRequest(uint32_t token, uint32_t reqtype); - void checkForRequest(); - void loadRequest(); - IdEditDialog *mEditDialog; - bool mWaitingForRequest; - uint32_t mRequestToken; - uint32_t mRequestType; + TokenQueue *mIdQueue; /* UI - from Designer */ Ui::IdDialog ui; diff --git a/retroshare-gui/src/gui/Identity/IdEditDialog.cpp b/retroshare-gui/src/gui/Identity/IdEditDialog.cpp index 37b96e703..ca3a9fa90 100644 --- a/retroshare-gui/src/gui/Identity/IdEditDialog.cpp +++ b/retroshare-gui/src/gui/Identity/IdEditDialog.cpp @@ -22,12 +22,15 @@ */ #include "gui/Identity/IdEditDialog.h" +#include "util/TokenQueue.h" #include #include #include +#define IDEDITDIALOG_LOADID 1 + /** Constructor */ IdEditDialog::IdEditDialog(QWidget *parent) : QWidget(parent) @@ -39,6 +42,7 @@ IdEditDialog::IdEditDialog(QWidget *parent) connect(ui.pushButton_Update, SIGNAL( clicked( void ) ), this, SLOT( updateId( void ) ) ); connect(ui.pushButton_Cancel, SIGNAL( clicked( void ) ), this, SLOT( cancelId( void ) ) ); + mIdQueue = new TokenQueue(rsIdentity, this); } void IdEditDialog::setupNewId(bool pseudo) @@ -98,7 +102,19 @@ void IdEditDialog::updateIdType(bool pseudo) } -void IdEditDialog::setupExistingId(uint32_t token) +void IdEditDialog::setupExistingId(std::string keyId) +{ + RsTokReqOptions opts; + + std::list groupIds; + groupIds.push_back(keyId); + + uint32_t token; + mIdQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, groupIds, IDEDITDIALOG_LOADID); +} + + +void IdEditDialog::loadExistingId(uint32_t token) { ui.checkBox_NewId->setChecked(false); ui.checkBox_NewId->setEnabled(false); @@ -106,8 +122,8 @@ void IdEditDialog::setupExistingId(uint32_t token) ui.radioButton_Pseudo->setEnabled(false); /* get details from libretroshare */ - RsIdData data; - if (!rsIdentity->getIdentity(token, data)) + RsIdGroup data; + if (!rsIdentity->getGroupData(token, data)) { ui.lineEdit_KeyId->setText("ERROR KEYID INVALID"); ui.lineEdit_Nickname->setText(""); @@ -133,8 +149,10 @@ void IdEditDialog::setupExistingId(uint32_t token) // force - incase it wasn't triggered. IdTypeToggled(true); - ui.lineEdit_Nickname->setText(QString::fromStdString(data.mNickname)); - ui.lineEdit_KeyId->setText(QString::fromStdString(data.mKeyId)); + //ui.lineEdit_Nickname->setText(QString::fromStdString(data.mNickname)); + //ui.lineEdit_KeyId->setText(QString::fromStdString(data.mKeyId)); + ui.lineEdit_Nickname->setText(QString::fromStdString(data.mMeta.mGroupName)); + ui.lineEdit_KeyId->setText(QString::fromStdString(data.mMeta.mGroupId)); if (pseudo) { @@ -166,12 +184,12 @@ void IdEditDialog::setupExistingId(uint32_t token) void IdEditDialog::updateId() { - RsIdData rid; + RsIdGroup rid; // Must set, Nickname, KeyId(if existing), mIdType, GpgId. - rid.mNickname = ui.lineEdit_Nickname->text().toStdString(); + rid.mMeta.mGroupName = ui.lineEdit_Nickname->text().toStdString(); - if (rid.mNickname.size() < 2) + if (rid.mMeta.mGroupName.size() < 2) { std::cerr << "IdEditDialog::updateId() Nickname too short"; std::cerr << std::endl; @@ -181,11 +199,11 @@ void IdEditDialog::updateId() rid.mIdType = RSID_RELATION_YOURSELF; if (ui.checkBox_NewId->isChecked()) { - rid.mKeyId = ""; + rid.mMeta.mGroupId = ""; } else { - rid.mKeyId = ui.lineEdit_KeyId->text().toStdString(); + rid.mMeta.mGroupId = ui.lineEdit_KeyId->text().toStdString(); } if (ui.radioButton_GpgId->isChecked()) @@ -207,7 +225,8 @@ void IdEditDialog::updateId() rid.mGpgEmail = ""; } - rsIdentity->updateIdentity(rid); + // TODO. + //rsIdentity->updateIdentity(rid); hide(); return; @@ -225,4 +244,13 @@ void IdEditDialog::clearDialog() } +void IdEditDialog::loadRequest(const TokenQueue *queue, const TokenRequest &req) +{ + std::cerr << "IdDialog::loadRequest() UserType: " << req.mUserType; + std::cerr << std::endl; + + // only one here! + loadExistingId(req.mToken); +} + diff --git a/retroshare-gui/src/gui/Identity/IdEditDialog.h b/retroshare-gui/src/gui/Identity/IdEditDialog.h index 8f910f975..f6b29a5a4 100644 --- a/retroshare-gui/src/gui/Identity/IdEditDialog.h +++ b/retroshare-gui/src/gui/Identity/IdEditDialog.h @@ -28,7 +28,9 @@ #include -class IdEditDialog : public QWidget +#include "util/TokenQueue.h" + +class IdEditDialog : public QWidget, public TokenResponse { Q_OBJECT @@ -36,7 +38,10 @@ public: IdEditDialog(QWidget *parent = 0); void setupNewId(bool pseudo); - void setupExistingId(uint32_t token); + void setupExistingId(std::string keyId); + void loadExistingId(uint32_t token); + +void loadRequest(const TokenQueue *queue, const TokenRequest &req); private slots: @@ -52,6 +57,7 @@ protected: Ui::IdEditDialog ui; + TokenQueue *mIdQueue; }; #endif diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoAddDialog.cpp b/retroshare-gui/src/gui/PhotoShare/PhotoAddDialog.cpp index 7e6397f38..49e2a00a5 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoAddDialog.cpp +++ b/retroshare-gui/src/gui/PhotoShare/PhotoAddDialog.cpp @@ -107,7 +107,7 @@ void PhotoAddDialog::publishAlbum() album.mShareOptions.mCommentMode = 0; album.mShareOptions.mResizeMode = 0; - album.mTitle = ui.lineEdit_Title->text().toStdString(); + album.mMeta.mGroupName = ui.lineEdit_Title->text().toStdString(); album.mCategory = "Unknown"; album.mCaption = ui.lineEdit_Caption->text().toStdString(); album.mWhere = ui.lineEdit_Where->text().toStdString(); @@ -122,10 +122,17 @@ void PhotoAddDialog::publishAlbum() { RsPhotoPhoto photo; PhotoItem *item = ui.scrollAreaWidgetContents->getPhotoIdx(i); - photo = item->mDetails; + + if (!item->mIsPhoto) + { + std::cerr << "PhotoAddDialog::publishAlbum() MAJOR ERROR!"; + std::cerr << std::endl; + } + + photo = item->mPhotoDetails; item->getPhotoThumbnail(photo.mThumbnail); - photo.mAlbumId = album.mAlbumId; + photo.mMeta.mGroupId = album.mMeta.mGroupId; photo.mOrder = i; /* scale photo if needed */ diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoDetailsDialog.cpp b/retroshare-gui/src/gui/PhotoShare/PhotoDetailsDialog.cpp index 42ae09461..d94573f71 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoDetailsDialog.cpp +++ b/retroshare-gui/src/gui/PhotoShare/PhotoDetailsDialog.cpp @@ -60,14 +60,28 @@ void PhotoDetailsDialog::refreshDetails() //ui.comboBox_Category= mPhotoItem->mDetails.mCaption; - ui.lineEdit_Caption->setText(QString::fromStdString(mPhotoItem->mDetails.mCaption)); - ui.textEdit_Description->setText(QString::fromStdString(mPhotoItem->mDetails.mDescription)); - ui.lineEdit_Photographer->setText(QString::fromStdString(mPhotoItem->mDetails.mPhotographer)); - ui.lineEdit_Where->setText(QString::fromStdString(mPhotoItem->mDetails.mWhere)); - ui.lineEdit_When->setText(QString::fromStdString(mPhotoItem->mDetails.mWhen)); - ui.lineEdit_Other->setText(QString::fromStdString(mPhotoItem->mDetails.mOther)); - ui.lineEdit_Title->setText(QString::fromStdString(mPhotoItem->mDetails.mTitle)); - ui.lineEdit_HashTags->setText(QString::fromStdString(mPhotoItem->mDetails.mHashTags)); + if (mPhotoItem->mIsPhoto) + { + ui.lineEdit_Caption->setText(QString::fromStdString(mPhotoItem->mPhotoDetails.mCaption)); + ui.textEdit_Description->setText(QString::fromStdString(mPhotoItem->mPhotoDetails.mDescription)); + ui.lineEdit_Photographer->setText(QString::fromStdString(mPhotoItem->mPhotoDetails.mPhotographer)); + ui.lineEdit_Where->setText(QString::fromStdString(mPhotoItem->mPhotoDetails.mWhere)); + ui.lineEdit_When->setText(QString::fromStdString(mPhotoItem->mPhotoDetails.mWhen)); + ui.lineEdit_Other->setText(QString::fromStdString(mPhotoItem->mPhotoDetails.mOther)); + ui.lineEdit_Title->setText(QString::fromStdString(mPhotoItem->mPhotoDetails.mMeta.mMsgName)); + ui.lineEdit_HashTags->setText(QString::fromStdString(mPhotoItem->mPhotoDetails.mHashTags)); + } + else + { + ui.lineEdit_Caption->setText(QString::fromStdString(mPhotoItem->mAlbumDetails.mCaption)); + ui.textEdit_Description->setText(QString::fromStdString(mPhotoItem->mAlbumDetails.mDescription)); + ui.lineEdit_Photographer->setText(QString::fromStdString(mPhotoItem->mAlbumDetails.mPhotographer)); + ui.lineEdit_Where->setText(QString::fromStdString(mPhotoItem->mAlbumDetails.mWhere)); + ui.lineEdit_When->setText(QString::fromStdString(mPhotoItem->mAlbumDetails.mWhen)); + ui.lineEdit_Other->setText(QString::fromStdString(mPhotoItem->mAlbumDetails.mOther)); + ui.lineEdit_Title->setText(QString::fromStdString(mPhotoItem->mAlbumDetails.mMeta.mGroupName)); + ui.lineEdit_HashTags->setText(QString::fromStdString(mPhotoItem->mAlbumDetails.mHashTags)); + } const QPixmap *qtn = mPhotoItem->getPixmap(); QPixmap cpy(*qtn); @@ -111,14 +125,28 @@ void PhotoDetailsDialog::saveDetails() //mPhotoItem->mDetails.mCaption = ui.comboBox_Category; - mPhotoItem->mDetails.mCaption = ui.lineEdit_Caption->text().toStdString(); - mPhotoItem->mDetails.mDescription = ui.textEdit_Description->toPlainText().toStdString(); - mPhotoItem->mDetails.mPhotographer = ui.lineEdit_Photographer->text().toStdString(); - mPhotoItem->mDetails.mWhere = ui.lineEdit_Where->text().toStdString(); - mPhotoItem->mDetails.mWhen = ui.lineEdit_When->text().toStdString(); - mPhotoItem->mDetails.mOther = ui.lineEdit_Other->text().toStdString(); - mPhotoItem->mDetails.mTitle = ui.lineEdit_Title->text().toStdString(); - mPhotoItem->mDetails.mHashTags = ui.lineEdit_HashTags->text().toStdString(); + if (mPhotoItem->mIsPhoto) + { + mPhotoItem->mPhotoDetails.mCaption = ui.lineEdit_Caption->text().toStdString(); + mPhotoItem->mPhotoDetails.mDescription = ui.textEdit_Description->toPlainText().toStdString(); + mPhotoItem->mPhotoDetails.mPhotographer = ui.lineEdit_Photographer->text().toStdString(); + mPhotoItem->mPhotoDetails.mWhere = ui.lineEdit_Where->text().toStdString(); + mPhotoItem->mPhotoDetails.mWhen = ui.lineEdit_When->text().toStdString(); + mPhotoItem->mPhotoDetails.mOther = ui.lineEdit_Other->text().toStdString(); + mPhotoItem->mPhotoDetails.mMeta.mMsgName = ui.lineEdit_Title->text().toStdString(); + mPhotoItem->mPhotoDetails.mHashTags = ui.lineEdit_HashTags->text().toStdString(); + } + else + { + mPhotoItem->mAlbumDetails.mCaption = ui.lineEdit_Caption->text().toStdString(); + mPhotoItem->mAlbumDetails.mDescription = ui.textEdit_Description->toPlainText().toStdString(); + mPhotoItem->mAlbumDetails.mPhotographer = ui.lineEdit_Photographer->text().toStdString(); + mPhotoItem->mAlbumDetails.mWhere = ui.lineEdit_Where->text().toStdString(); + mPhotoItem->mAlbumDetails.mWhen = ui.lineEdit_When->text().toStdString(); + mPhotoItem->mAlbumDetails.mOther = ui.lineEdit_Other->text().toStdString(); + mPhotoItem->mAlbumDetails.mMeta.mGroupName = ui.lineEdit_Title->text().toStdString(); + mPhotoItem->mAlbumDetails.mHashTags = ui.lineEdit_HashTags->text().toStdString(); + } //QPixmap qtn = mPhotoItem->getPixmap(); //ui.label_Photo->setPixmap(qtn); diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp index 80db9ccf8..d38751a7f 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp +++ b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp @@ -197,7 +197,13 @@ void PhotoDialog::insertPhotosForSelectedAlbum() //std::list albumIds; if (mAlbumSelected) { - std::string albumId = mAlbumSelected->mDetails.mAlbumId; + if (mAlbumSelected->mIsPhoto) + { + std::cerr << "PhotoDialog::insertPhotosForSelectedAlbum() MAJOR ERROR!"; + std::cerr << std::endl; + } + + std::string albumId = mAlbumSelected->mAlbumDetails.mMeta.mGroupId; //albumIds.push_back(albumId); std::cerr << "PhotoDialog::insertPhotosForSelectedAlbum() AlbumId: " << albumId; @@ -300,7 +306,7 @@ void PhotoDialog::clearPhotos() void PhotoDialog::addAlbum(const RsPhotoAlbum &album) { - std::cerr << " PhotoDialog::addAlbum() AlbumId: " << album.mAlbumId << std::endl; + std::cerr << " PhotoDialog::addAlbum() AlbumId: " << album.mMeta.mGroupId << std::endl; PhotoItem *item = new PhotoItem(this, album); QLayout *alayout = ui.scrollAreaWidgetContents->layout(); @@ -310,8 +316,8 @@ void PhotoDialog::addAlbum(const RsPhotoAlbum &album) void PhotoDialog::addPhoto(const RsPhotoPhoto &photo) { - std::cerr << "PhotoDialog::addPhoto() AlbumId: " << photo.mAlbumId; - std::cerr << " PhotoId: " << photo.mId; + std::cerr << "PhotoDialog::addPhoto() AlbumId: " << photo.mMeta.mGroupId; + std::cerr << " PhotoId: " << photo.mMeta.mMsgId; std::cerr << std::endl; PhotoItem *item = new PhotoItem(this, photo); @@ -336,7 +342,8 @@ void PhotoDialog::requestAlbumList() std::list ids; RsTokReqOptions opts; - mPhotoQueue->genericRequest(TOKENREQ_GROUPLIST, opts, ids, 0); + uint32_t token; + mPhotoQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_LIST, opts, ids, 0); } @@ -364,7 +371,8 @@ void PhotoDialog::loadAlbumList(const uint32_t &token) void PhotoDialog::requestAlbumData(const std::list &ids) { RsTokReqOptions opts; - mPhotoQueue->genericRequest(TOKENREQ_GROUPDATA, opts, ids, 0); + uint32_t token; + mPhotoQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, ids, 0); } @@ -381,7 +389,7 @@ bool PhotoDialog::loadAlbumData(const uint32_t &token) RsPhotoAlbum album; if (rsPhoto->getAlbum(token, album)) { - std::cerr << " PhotoDialog::addAlbum() AlbumId: " << album.mAlbumId << std::endl; + std::cerr << " PhotoDialog::addAlbum() AlbumId: " << album.mMeta.mGroupId << std::endl; PhotoItem *item = new PhotoItem(this, album); QLayout *alayout = ui.scrollAreaWidgetContents->layout(); @@ -403,7 +411,8 @@ void PhotoDialog::requestPhotoList(const std::string &albumId) std::list ids; ids.push_back(albumId); RsTokReqOptions opts; - mPhotoQueue->genericRequest(TOKENREQ_MSGLIST, opts, ids, 0); + uint32_t token; + mPhotoQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_LIST, opts, ids, 0); } @@ -425,7 +434,8 @@ void PhotoDialog::loadPhotoList(const uint32_t &token) void PhotoDialog::requestPhotoData(const std::list &photoIds) { RsTokReqOptions opts; - mPhotoQueue->genericRequest(TOKENREQ_MSGDATA, opts, photoIds, 0); + uint32_t token; + mPhotoQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, photoIds, 0); } @@ -442,8 +452,8 @@ void PhotoDialog::loadPhotoData(const uint32_t &token) if (rsPhoto->getPhoto(token, photo)) { - std::cerr << "PhotoDialog::addPhoto() AlbumId: " << photo.mAlbumId; - std::cerr << " PhotoId: " << photo.mId; + std::cerr << "PhotoDialog::addPhoto() AlbumId: " << photo.mMeta.mGroupId; + std::cerr << " PhotoId: " << photo.mMeta.mMsgId; std::cerr << std::endl; PhotoItem *item = new PhotoItem(this, photo); @@ -470,17 +480,47 @@ void PhotoDialog::loadRequest(const TokenQueue *queue, const TokenRequest &req) /* now switch on req */ switch(req.mType) { - case TOKENREQ_GROUPLIST: - loadAlbumList(req.mToken); + case TOKENREQ_GROUPINFO: + switch(req.mAnsType) + { + case RS_TOKREQ_ANSTYPE_LIST: + loadAlbumList(req.mToken); + break; + case RS_TOKREQ_ANSTYPE_DATA: + loadAlbumData(req.mToken); + break; + default: + std::cerr << "PhotoDialog::loadRequest() ERROR: GROUP: INVALID ANS TYPE"; + std::cerr << std::endl; + break; + } break; - case TOKENREQ_GROUPDATA: - loadAlbumData(req.mToken); + case TOKENREQ_MSGINFO: + switch(req.mAnsType) + { + case RS_TOKREQ_ANSTYPE_LIST: + loadPhotoList(req.mToken); + break; + //case RS_TOKREQ_ANSTYPE_DATA: + // loadPhotoData(req.mToken); + // break; + default: + std::cerr << "PhotoDialog::loadRequest() ERROR: MSG: INVALID ANS TYPE"; + std::cerr << std::endl; + break; + } break; - case TOKENREQ_MSGLIST: - loadPhotoList(req.mToken); - break; - case TOKENREQ_MSGDATA: - loadPhotoData(req.mToken); + case TOKENREQ_MSGRELATEDINFO: + switch(req.mAnsType) + { + case RS_TOKREQ_ANSTYPE_DATA: + loadPhotoData(req.mToken); + break; + default: + std::cerr << "PhotoDialog::loadRequest() ERROR: MSG: INVALID ANS TYPE"; + std::cerr << std::endl; + break; + } break; default: std::cerr << "PhotoDialog::loadRequest() ERROR: INVALID TYPE"; diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoItem.cpp b/retroshare-gui/src/gui/PhotoShare/PhotoItem.cpp index 3e087f694..e5475005e 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoItem.cpp +++ b/retroshare-gui/src/gui/PhotoShare/PhotoItem.cpp @@ -46,7 +46,8 @@ PhotoItem::PhotoItem(PhotoHolder *parent, const RsPhotoAlbum &album) setAttribute ( Qt::WA_DeleteOnClose, true ); - mDetails = *( (RsPhotoPhoto *) &(album)); + mIsPhoto = false; + mAlbumDetails = album; updateAlbumText(album); updateImage(album.mThumbnail); @@ -61,7 +62,8 @@ PhotoItem::PhotoItem(PhotoHolder *parent, const RsPhotoPhoto &photo) setAttribute ( Qt::WA_DeleteOnClose, true ); - mDetails = *( (RsPhotoPhoto *) &(photo)); + mIsPhoto = true; + mPhotoDetails = photo; updatePhotoText(photo); updateImage(photo.mThumbnail); @@ -80,6 +82,8 @@ PhotoItem::PhotoItem(PhotoHolder *parent, std::string path) // for new photos. QString dummyString("dummytext"); titleLabel->setText(QString("NEW PHOTO")); + mIsPhoto = true; + fromBoldLabel->setText(QString("From:")); fromLabel->setText(QString("Ourselves")); diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoItem.h b/retroshare-gui/src/gui/PhotoShare/PhotoItem.h index 001129749..2fe4e4fc0 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoItem.h +++ b/retroshare-gui/src/gui/PhotoShare/PhotoItem.h @@ -61,7 +61,9 @@ public: const QPixmap *getPixmap(); // details are public - so that can be easily edited. - RsPhotoPhoto mDetails; + bool mIsPhoto; + RsPhotoPhoto mPhotoDetails; + RsPhotoAlbum mAlbumDetails; //private slots: diff --git a/retroshare-gui/src/gui/WikiPoos/WikiAddDialog.cpp b/retroshare-gui/src/gui/WikiPoos/WikiAddDialog.cpp index b902383e6..7ae374b5a 100644 --- a/retroshare-gui/src/gui/WikiPoos/WikiAddDialog.cpp +++ b/retroshare-gui/src/gui/WikiPoos/WikiAddDialog.cpp @@ -61,7 +61,7 @@ void WikiAddDialog::createGroup() group.mShareOptions.mCommentMode = 0; group.mShareOptions.mResizeMode = 0; - group.mName = ui.lineEdit_Name->text().toStdString(); + group.mMeta.mGroupName = ui.lineEdit_Name->text().toStdString(); group.mCategory = "Unknown"; rsWiki->createGroup(group); diff --git a/retroshare-gui/src/gui/WikiPoos/WikiDialog.cpp b/retroshare-gui/src/gui/WikiPoos/WikiDialog.cpp index 61b97ef6c..9c5f35cfc 100644 --- a/retroshare-gui/src/gui/WikiPoos/WikiDialog.cpp +++ b/retroshare-gui/src/gui/WikiPoos/WikiDialog.cpp @@ -509,7 +509,8 @@ void WikiDialog::requestGroupList() std::list ids; RsTokReqOptions opts; - mWikiQueue->genericRequest(TOKENREQ_GROUPLIST, opts, ids, WIKIDIALOG_LISTING_GROUPLIST); + uint32_t token; + mWikiQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_LIST, opts, ids, WIKIDIALOG_LISTING_GROUPLIST); } void WikiDialog::loadGroupList(const uint32_t &token) @@ -534,7 +535,8 @@ void WikiDialog::loadGroupList(const uint32_t &token) void WikiDialog::requestGroupData(const std::list &groupIds) { RsTokReqOptions opts; - mWikiQueue->genericRequest(TOKENREQ_GROUPDATA, opts, groupIds, WIKIDIALOG_LISTING_GROUPDATA); + uint32_t token; + mWikiQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, groupIds, WIKIDIALOG_LISTING_GROUPDATA); } void WikiDialog::loadGroupData(const uint32_t &token) @@ -552,18 +554,18 @@ void WikiDialog::loadGroupData(const uint32_t &token) { /* Add Widget, and request Pages */ - std::cerr << "WikiDialog::addGroup() GroupId: " << group.mGroupId; - std::cerr << " Group: " << group.mName; + std::cerr << "WikiDialog::addGroup() GroupId: " << group.mMeta.mGroupId; + std::cerr << " Group: " << group.mMeta.mGroupName; std::cerr << std::endl; QTreeWidgetItem *groupItem = new QTreeWidgetItem(NULL); - groupItem->setText(WIKI_GROUP_COL_GROUPNAME, QString::fromStdString(group.mName)); - groupItem->setText(WIKI_GROUP_COL_GROUPID, QString::fromStdString(group.mGroupId)); + groupItem->setText(WIKI_GROUP_COL_GROUPNAME, QString::fromStdString(group.mMeta.mGroupName)); + groupItem->setText(WIKI_GROUP_COL_GROUPID, QString::fromStdString(group.mMeta.mGroupId)); ui.treeWidget_Pages->addTopLevelItem(groupItem); /* request pages */ std::list groupIds; - groupIds.push_back(group.mGroupId); + groupIds.push_back(group.mMeta.mGroupId); requestOriginalPages(groupIds); } @@ -579,7 +581,8 @@ void WikiDialog::requestOriginalPages(const std::list &groupIds) { RsTokReqOptions opts; opts.mOptions = RS_TOKREQOPT_MSG_ORIGMSG; - mWikiQueue->genericRequest(TOKENREQ_MSGLIST, opts, groupIds, WIKIDIALOG_LISTING_ORIGINALPAGES); + uint32_t token; + mWikiQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_LIST, opts, groupIds, WIKIDIALOG_LISTING_ORIGINALPAGES); } void WikiDialog::loadOriginalPages(const uint32_t &token) @@ -609,7 +612,8 @@ void WikiDialog::requestLatestPages(const std::list &msgIds) { RsTokReqOptions opts; opts.mOptions = RS_TOKREQOPT_MSG_LATEST; - mWikiQueue->genericRequest(TOKENREQ_MSGRELATEDLIST, opts, msgIds, WIKIDIALOG_LISTING_LATESTPAGES); + uint32_t token; + mWikiQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_LIST, opts, msgIds, WIKIDIALOG_LISTING_LATESTPAGES); } void WikiDialog::loadLatestPages(const uint32_t &token) @@ -638,7 +642,8 @@ void WikiDialog::loadLatestPages(const uint32_t &token) void WikiDialog::requestPages(const std::list &msgIds) { RsTokReqOptions opts; - mWikiQueue->genericRequest(TOKENREQ_MSGDATA, opts, msgIds, WIKIDIALOG_LISTING_PAGES); + uint32_t token; + mWikiQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, WIKIDIALOG_LISTING_PAGES); } void WikiDialog::loadPages(const uint32_t &token) @@ -666,7 +671,7 @@ void WikiDialog::loadPages(const uint32_t &token) QTreeWidgetItem *tmpItem = ui.treeWidget_Pages->topLevelItem(nIndex); std::string tmpid = tmpItem->data(WIKI_GROUP_COL_GROUPID, Qt::DisplayRole).toString().toStdString(); - if (tmpid == page.mGroupId) + if (tmpid == page.mMeta.mGroupId) { groupItem = tmpItem; break; @@ -683,14 +688,14 @@ void WikiDialog::loadPages(const uint32_t &token) } - std::cerr << "WikiDialog::loadPages() PageId: " << page.mPageId; - std::cerr << " Page: " << page.mName; + std::cerr << "WikiDialog::loadPages() PageId: " << page.mMeta.mMsgId; + std::cerr << " Page: " << page.mMeta.mMsgName; std::cerr << std::endl; QTreeWidgetItem *pageItem = new QTreeWidgetItem(NULL); - pageItem->setText(WIKI_GROUP_COL_PAGENAME, QString::fromStdString(page.mName)); - pageItem->setText(WIKI_GROUP_COL_PAGEID, QString::fromStdString(page.mPageId)); - pageItem->setText(WIKI_GROUP_COL_ORIGPAGEID, QString::fromStdString(page.mOrigPageId)); + pageItem->setText(WIKI_GROUP_COL_PAGENAME, QString::fromStdString(page.mMeta.mMsgName)); + pageItem->setText(WIKI_GROUP_COL_PAGEID, QString::fromStdString(page.mMeta.mMsgId)); + pageItem->setText(WIKI_GROUP_COL_ORIGPAGEID, QString::fromStdString(page.mMeta.mOrigMsgId)); groupItem->addChild(pageItem); @@ -719,7 +724,8 @@ void WikiDialog::requestModPageList(const std::string &origMsgId) std::list msgIds; msgIds.push_back(origMsgId); - mWikiQueue->genericRequest(TOKENREQ_MSGRELATEDLIST, opts, msgIds, WIKIDIALOG_MOD_LIST); + uint32_t token; + mWikiQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_LIST, opts, msgIds, WIKIDIALOG_MOD_LIST); } @@ -749,8 +755,9 @@ void WikiDialog::loadModPageList(const uint32_t &token) void WikiDialog::requestModPages(const std::list &msgIds) { RsTokReqOptions opts; - opts.mOptions = RS_TOKREQOPT_MSG_LATEST; - mWikiQueue->genericRequest(TOKENREQ_MSGDATA, opts, msgIds, WIKIDIALOG_MOD_PAGES); + + uint32_t token; + mWikiQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, WIKIDIALOG_MOD_PAGES); } @@ -765,13 +772,13 @@ void WikiDialog::loadModPages(const uint32_t &token) RsWikiPage page; if (rsWiki->getMsgData(token, page)) { - std::cerr << "WikiDialog::loadModPages() PageId: " << page.mPageId; - std::cerr << " Page: " << page.mName; + std::cerr << "WikiDialog::loadModPages() PageId: " << page.mMeta.mMsgId; + std::cerr << " Page: " << page.mMeta.mMsgName; std::cerr << std::endl; QTreeWidgetItem *modItem = new QTreeWidgetItem(NULL); - modItem->setText(WIKI_MODS_COL_ORIGPAGEID, QString::fromStdString(page.mOrigPageId)); - modItem->setText(WIKI_MODS_COL_PAGEID, QString::fromStdString(page.mPageId)); + modItem->setText(WIKI_MODS_COL_ORIGPAGEID, QString::fromStdString(page.mMeta.mOrigMsgId)); + modItem->setText(WIKI_MODS_COL_PAGEID, QString::fromStdString(page.mMeta.mMsgId)); ui.treeWidget_Mods->addTopLevelItem(modItem); } @@ -794,7 +801,8 @@ void WikiDialog::requestWikiPage(const std::string &msgId) std::list msgIds; msgIds.push_back(msgId); - mWikiQueue->genericRequest(TOKENREQ_MSGDATA, opts, msgIds, WIKIDIALOG_WIKI_PAGE); + uint32_t token; + mWikiQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, WIKIDIALOG_WIKI_PAGE); } @@ -810,8 +818,8 @@ void WikiDialog::loadWikiPage(const uint32_t &token) RsWikiPage page; if (rsWiki->getMsgData(token, page)) { - std::cerr << "WikiDialog::loadModPages() PageId: " << page.mPageId; - std::cerr << " Page: " << page.mName; + std::cerr << "WikiDialog::loadModPages() PageId: " << page.mMeta.mMsgId; + std::cerr << " Page: " << page.mMeta.mMsgName; std::cerr << std::endl; updateWikiPage(page); diff --git a/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.cpp b/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.cpp index b9ba9b522..92e124848 100644 --- a/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.cpp +++ b/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.cpp @@ -43,7 +43,7 @@ void WikiEditDialog::setGroup(RsWikiGroup &group) { mWikiGroup = group; - ui.lineEdit_Group->setText(QString::fromStdString(mWikiGroup.mName)); + ui.lineEdit_Group->setText(QString::fromStdString(mWikiGroup.mMeta.mGroupName)); } @@ -52,8 +52,8 @@ void WikiEditDialog::setPreviousPage(RsWikiPage &page) mNewPage = false; mWikiPage = page; - ui.lineEdit_Page->setText(QString::fromStdString(mWikiPage.mName)); - ui.lineEdit_PrevVersion->setText(QString::fromStdString(mWikiPage.mPageId)); + ui.lineEdit_Page->setText(QString::fromStdString(mWikiPage.mMeta.mMsgName)); + ui.lineEdit_PrevVersion->setText(QString::fromStdString(mWikiPage.mMeta.mMsgId)); ui.textEdit->setPlainText(QString::fromStdString(mWikiPage.mPage)); } @@ -90,18 +90,18 @@ void WikiEditDialog::submitEdit() { if (mNewPage) { - mWikiPage.mGroupId = mWikiGroup.mGroupId; - mWikiPage.mOrigPageId = ""; - mWikiPage.mPageId = ""; + mWikiPage.mMeta.mGroupId = mWikiGroup.mMeta.mGroupId; + mWikiPage.mMeta.mOrigMsgId = ""; + mWikiPage.mMeta.mMsgId = ""; mWikiPage.mPrevId = ""; } else { - mWikiPage.mPrevId = mWikiPage.mPageId; - mWikiPage.mPageId = ""; + mWikiPage.mPrevId = mWikiPage.mMeta.mMsgId; + mWikiPage.mMeta.mMsgId = ""; } - mWikiPage.mName = ui.lineEdit_Page->text().toStdString(); + mWikiPage.mMeta.mMsgName = ui.lineEdit_Page->text().toStdString(); mWikiPage.mPage = ui.textEdit->toPlainText().toStdString(); rsWiki->createPage(mWikiPage); @@ -133,7 +133,8 @@ void WikiEditDialog::requestGroup(const std::string &groupId) ids.push_back(groupId); RsTokReqOptions opts; - mWikiQueue->genericRequest(TOKENREQ_GROUPDATA, opts, ids, 0); + uint32_t token; + mWikiQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, ids, 0); } void WikiEditDialog::loadGroup(const uint32_t &token) @@ -156,7 +157,9 @@ void WikiEditDialog::requestPage(const std::string &msgId) std::list ids; ids.push_back(msgId); RsTokReqOptions opts; - mWikiQueue->genericRequest(TOKENREQ_MSGDATA, opts, ids, 0); + + uint32_t token; + mWikiQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, ids, 0); } void WikiEditDialog::loadPage(const uint32_t &token) @@ -181,10 +184,10 @@ void WikiEditDialog::loadRequest(const TokenQueue *queue, const TokenRequest &re /* now switch on req */ switch(req.mType) { - case TOKENREQ_GROUPDATA: + case TOKENREQ_GROUPINFO: loadGroup(req.mToken); break; - case TOKENREQ_MSGDATA: + case TOKENREQ_MSGRELATEDINFO: loadPage(req.mToken); break; default: diff --git a/retroshare-gui/src/gui/forumsv2/CreateForumV2.cpp b/retroshare-gui/src/gui/forumsv2/CreateForumV2.cpp new file mode 100644 index 000000000..90d31dbcf --- /dev/null +++ b/retroshare-gui/src/gui/forumsv2/CreateForumV2.cpp @@ -0,0 +1,227 @@ +/**************************************************************** + * 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 "util/misc.h" +#include "CreateForumV2.h" +#include "gui/common/PeerDefs.h" + +#include + +#include +#include + +/** Constructor */ +CreateForumV2::CreateForumV2(QWidget *parent) +: QDialog(parent) +{ + /* Invoke the Qt Designer generated object setup routine */ + ui.setupUi(this); + + // connect up the buttons. + connect( ui.cancelButton, SIGNAL( clicked ( bool ) ), this, SLOT( cancelForum( ) ) ); + connect( ui.createButton, SIGNAL( clicked ( bool ) ), this, SLOT( createForum( ) ) ); + connect( ui.pubKeyShare_cb, SIGNAL( clicked() ), this, SLOT( setShareList( ) )); + connect( ui.keyShareList, SIGNAL(itemChanged( QTreeWidgetItem *, int ) ), + this, SLOT(togglePersonItem( QTreeWidgetItem *, int ) )); + + if(!ui.pubKeyShare_cb->isChecked()){ + + ui.contactsdockWidget->hide(); + this->resize(this->size().width() - ui.contactsdockWidget->size().width(), + this->size().height()); + } + + newForum(); +} + +void CreateForumV2::newForum() +{ + /* enforce Public for the moment */ + ui.typePublic->setChecked(true); + + ui.typePrivate->setEnabled(false); + ui.typeEncrypted->setEnabled(true); + +#ifdef RS_RELEASE_VERSION + ui.typePrivate->setVisible(false); + ui.typeEncrypted->setVisible(true); +#endif + + ui.msgAnon->setChecked(true); + //ui.msgAuth->setEnabled(false); + + ui.forumName->clear(); + ui.forumDesc->clear(); +} + +void CreateForumV2::togglePersonItem( QTreeWidgetItem *item, int /*col*/ ) +{ + + /* extract id */ + std::string id = (item -> text(1)).toStdString(); + + /* get state */ + bool checked = (Qt::Checked == item -> checkState(0)); /* alway column 0 */ + + /* call control fns */ + std::list::iterator lit = std::find(mShareList.begin(), mShareList.end(), id); + + if(checked && (lit == mShareList.end())){ + + // make sure ids not added already + mShareList.push_back(id); + + }else + if(lit != mShareList.end()){ + + mShareList.erase(lit); + + } + + return; +} + +void CreateForumV2::createForum() +{ + QString name = misc::removeNewLine(ui.forumName->text()); + QString desc = ui.forumDesc->toPlainText(); //toHtml(); + uint32_t flags = 0; + + if(name.isEmpty()) + { /* error message */ + QMessageBox::warning(this, "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 (rsForums) + { + std::string forumId = rsForums->createForum(name.toStdWString(), + desc.toStdWString(), flags); + + if(ui.pubKeyShare_cb->isChecked()) + rsForums->forumShareKeys(forumId, mShareList); + } + + close(); +} + +void CreateForumV2::setShareList(){ + + if(ui.pubKeyShare_cb->isChecked()){ + this->resize(this->size().width() + ui.contactsdockWidget->size().width(), + this->size().height()); + ui.contactsdockWidget->show(); + + + if (!rsPeers) + { + /* not ready yet! */ + return; + } + + std::list peers; + std::list::iterator it; + + rsPeers->getFriendList(peers); + + /* get a link to the table */ + QTreeWidget *shareWidget = ui.keyShareList; + + QList items; + + for(it = peers.begin(); it != peers.end(); it++) + { + + RsPeerDetails detail; + if (!rsPeers->getPeerDetails(*it, detail)) + { + continue; /* BAD */ + } + + /* make a widget per friend */ + QTreeWidgetItem *item = new QTreeWidgetItem((QTreeWidget*)0); + + item -> setText(0, PeerDefs::nameWithLocation(detail)); + if (detail.state & RS_PEER_STATE_CONNECTED) { + item -> setTextColor(0,(Qt::darkBlue)); + } + item -> setSizeHint(0, QSize( 17,17 ) ); + + item -> setText(1, QString::fromStdString(detail.id)); + + item -> setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled); + item -> setCheckState(0, Qt::Unchecked); + + + /* add to the list */ + items.append(item); + } + + /* remove old items */ + shareWidget->clear(); + shareWidget->setColumnCount(1); + + /* add the items in! */ + shareWidget->insertTopLevelItems(0, items); + + shareWidget->update(); /* update display */ + + }else{ // hide share widget + ui.contactsdockWidget->hide(); + this->resize(this->size().width() - ui.contactsdockWidget->size().width(), + this->size().height()); + mShareList.clear(); + } + +} + + +void CreateForumV2::cancelForum() +{ + close(); +} diff --git a/retroshare-gui/src/gui/forumsv2/CreateForumV2.h b/retroshare-gui/src/gui/forumsv2/CreateForumV2.h new file mode 100644 index 000000000..ae88827fe --- /dev/null +++ b/retroshare-gui/src/gui/forumsv2/CreateForumV2.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_FORUMV2_DIALOG_H +#define _CREATE_FORUMV2_DIALOG_H + +#include "ui_CreateForumV2.h" + +class CreateForumV2 : public QDialog +{ + Q_OBJECT + +public: + CreateForumV2(QWidget *parent = 0); + +void newForum(); /* cleanup */ + + /** Qt Designer generated object */ + Ui::CreateForumV2 ui; + + QPixmap picture; + +private slots: + + /* actions to take.... */ +void createForum(); +void cancelForum(); + +// set private forum key share list +void setShareList(); + +// when user checks a person in share list checkboxes +void togglePersonItem(QTreeWidgetItem* item, int col); + +private: + +std::list mShareList; + +}; + +#endif + diff --git a/retroshare-gui/src/gui/forumsv2/CreateForumV2.ui b/retroshare-gui/src/gui/forumsv2/CreateForumV2.ui new file mode 100644 index 000000000..6ab6dcf95 --- /dev/null +++ b/retroshare-gui/src/gui/forumsv2/CreateForumV2.ui @@ -0,0 +1,374 @@ + + + CreateForumV2 + + + + 0 + 0 + 672 + 495 + + + + Create new Forum + + + + :/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/konversation64.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 Forum</span></p></body></html> + + + + + + + + + + QFrame::NoFrame + + + QFrame::Raised + + + + + + + + Name + + + + + + + + + + + + true + + + + 0 + 0 + + + + + 300 + 524287 + + + + + 220 + 0 + + + + + 0 + 0 + + + + check peers you would like to share private publish key with + + + false + + + QDockWidget::NoDockWidgetFeatures + + + Share Key With + + + + + 0 + + + 0 + + + + + + 0 + 4 + + + + + 20 + 0 + + + + + 300 + 16777215 + + + + + 220 + 0 + + + + + 200 + 0 + + + + true + + + + Contacts: + + + + + + + + + + + + + + Description + + + + + + + + + + + + Type: + + + + 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) + + + + + + + + + + Key Sharing + + + + 0 + + + 6 + + + + + Key recipients can publish to restricted-type channels, and can view and publish for private-type channels + + + Share Private Publish Key + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + Allowed Messages + + + + 0 + + + 6 + + + + + Authenticated Messages + + + + + + + Anonymous Messages + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + Qt::Horizontal + + + + 238 + 20 + + + + + + + + Cancel + + + + + + + Create + + + true + + + + + + + + + + + + + diff --git a/retroshare-gui/src/gui/forumsv2/CreateForumV2Msg.cpp b/retroshare-gui/src/gui/forumsv2/CreateForumV2Msg.cpp new file mode 100644 index 000000000..d20b5816f --- /dev/null +++ b/retroshare-gui/src/gui/forumsv2/CreateForumV2Msg.cpp @@ -0,0 +1,247 @@ +/**************************************************************** + * 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 "CreateForumV2Msg.h" + +#include +#include +#include +#include +#include +#include + +#include + +#include "gui/settings/rsharesettings.h" +#include "gui/RetroShareLink.h" +#include "gui/common/Emoticons.h" + +#include "util/misc.h" + +#include + + +/** Constructor */ +CreateForumV2Msg::CreateForumV2Msg(std::string fId, std::string pId) +: QMainWindow(NULL), mForumId(fId), mParentId(pId) +{ + /* Invoke the Qt Designer generated object setup routine */ + ui.setupUi(this); + setAttribute(Qt::WA_DeleteOnClose, true); + + Settings->loadWidgetInformation(this); + + connect( ui.forumMessage, SIGNAL( customContextMenuRequested( QPoint ) ), this, SLOT( forumMessageCostumPopupMenu( QPoint ) ) ); + + connect(ui.hashBox, SIGNAL(fileHashingFinished(QList)), this, SLOT(fileHashingFinished(QList))); + + // connect up the buttons. + connect( ui.postmessage_action, SIGNAL( triggered (bool) ), this, SLOT( createMsg( ) ) ); + connect( ui.close_action, SIGNAL( triggered (bool) ), this, SLOT( cancelMsg( ) ) ); + connect( ui.emoticonButton, SIGNAL(clicked()), this, SLOT(smileyWidgetForums())); + connect( ui.attachFileButton, SIGNAL(clicked() ), this , SLOT(addFile())); + connect( ui.pastersButton, SIGNAL(clicked() ), this , SLOT(pasteLink())); + + setAcceptDrops(true); + ui.hashBox->setDropWidget(this); + ui.hashBox->setAutoHide(false); + + newMsg(); +} + +/** context menu searchTablewidget2 **/ +void CreateForumV2Msg::forumMessageCostumPopupMenu( QPoint /*point*/ ) +{ + QMenu *contextMnu = ui.forumMessage->createStandardContextMenu(); + + contextMnu->addSeparator(); + QAction *pasteLinkAct = contextMnu->addAction(QIcon(":/images/pasterslink.png"), tr("Paste RetroShare Link"), this, SLOT(pasteLink())); + QAction *pasteLinkFullAct = contextMnu->addAction(QIcon(":/images/pasterslink.png"), tr("Paste full RetroShare Link"), this, SLOT(pasteLinkFull())); + + if (RSLinkClipboard::empty()) { + pasteLinkAct->setDisabled (true); + pasteLinkFullAct->setDisabled (true); + } + + contextMnu->exec(QCursor::pos()); + delete(contextMnu); +} + +void CreateForumV2Msg::newMsg() +{ + /* clear all */ + ForumInfo fi; + if (rsForums->getForumInfo(mForumId, fi)) + { + ForumMsgInfo msg; + + QString name = QString::fromStdWString(fi.forumName); + QString subj; + if ((mParentId != "") && (rsForums->getForumMessage(mForumId, mParentId, msg))) + { + QString title = QString::fromStdWString(msg.title); + name += " " + tr("In Reply to") + ": "; + name += title; + + QString text = title; + + if (text.startsWith("Re:", Qt::CaseInsensitive)) + { + subj = title; + } + else + { + subj = "Re: " + title; + } + + } + + ui.forumName->setText(misc::removeNewLine(name)); + ui.forumSubject->setText(misc::removeNewLine(subj)); + + if (!ui.forumSubject->text().isEmpty()) + { + ui.forumMessage->setFocus(); + } + else + { + ui.forumSubject->setFocus(); + } + + if (fi.forumFlags & RS_DISTRIB_AUTHEN_REQ) + { + ui.signBox->setChecked(true); + ui.signBox->setEnabled(false); + } + else + { + /* Uncheck sign box by default for anonymous forums */ + ui.signBox->setChecked(false); + ui.signBox->setEnabled(true); + } + } + + ui.forumMessage->setText(""); +} + +void CreateForumV2Msg::createMsg() +{ + QString name = misc::removeNewLine(ui.forumSubject->text()); + QString desc = ui.forumMessage->toHtml(); + + if(desc == QTextDocument(ui.forumMessage->toPlainText()).toHtml()) + desc = ui.forumMessage->toPlainText() ; + + if(name.isEmpty()) + { /* error message */ + QMessageBox::warning(this, tr("RetroShare"),tr("Please set a Forum Subject and Forum Message"), + QMessageBox::Ok, QMessageBox::Ok); + + return; //Don't add a empty Subject!! + } + + ForumMsgInfo msgInfo; + + msgInfo.forumId = mForumId; + msgInfo.threadId = ""; + msgInfo.parentId = mParentId; + msgInfo.msgId = ""; + + msgInfo.title = name.toStdWString(); + msgInfo.msg = desc.toStdWString(); + msgInfo.msgflags = 0; + + if (ui.signBox->isChecked()) + { + msgInfo.msgflags = RS_DISTRIB_AUTHEN_REQ; + } + + if ((msgInfo.msg == L"") && (msgInfo.title == L"")) + return; /* do nothing */ + + if (rsForums->ForumMessageSend(msgInfo) == true) { + close(); + } +} + +void CreateForumV2Msg::closeEvent (QCloseEvent * /*event*/) +{ + Settings->saveWidgetInformation(this); +} + +void CreateForumV2Msg::cancelMsg() +{ + close(); +} + +void CreateForumV2Msg::smileyWidgetForums() +{ + Emoticons::showSmileyWidget(this, ui.emoticonButton, SLOT(addSmileys()), false); +} + +void CreateForumV2Msg::addSmileys() +{ + ui.forumMessage->textCursor().insertText(qobject_cast(sender())->toolTip().split("|").first()); +} + +void CreateForumV2Msg::addFile() +{ + QStringList files; + if (misc::getOpenFileNames(this, RshareSettings::LASTDIR_EXTRAFILE, tr("Add Extra File"), "", files)) { + ui.hashBox->addAttachments(files); + } +} + +void CreateForumV2Msg::fileHashingFinished(QList hashedFiles) +{ + std::cerr << "CreateForumV2Msg::fileHashingFinished() started." << std::endl; + + QString mesgString; + + QList::iterator it; + for (it = hashedFiles.begin(); it != hashedFiles.end(); ++it) { + HashedFile& hashedFile = *it; + RetroShareLink link; + if (link.createFile(hashedFile.filename, hashedFile.size, QString::fromStdString(hashedFile.hash))) { + mesgString += link.toHtmlSize() + "
"; + } + } + +#ifdef CHAT_DEBUG + std::cerr << "CreateForumV2Msg::anchorClicked mesgString : " << mesgString.toStdString() << std::endl; +#endif + + if (!mesgString.isEmpty()) { + ui.forumMessage->textCursor().insertHtml(mesgString); + } + + ui.forumMessage->setFocus( Qt::OtherFocusReason ); +} + +void CreateForumV2Msg::pasteLink() +{ + ui.forumMessage->insertHtml(RSLinkClipboard::toHtml()) ; +} + +void CreateForumV2Msg::pasteLinkFull() +{ + ui.forumMessage->insertHtml(RSLinkClipboard::toHtmlFull()) ; +} diff --git a/retroshare-gui/src/gui/forumsv2/CreateForumV2Msg.h b/retroshare-gui/src/gui/forumsv2/CreateForumV2Msg.h new file mode 100644 index 000000000..53b670609 --- /dev/null +++ b/retroshare-gui/src/gui/forumsv2/CreateForumV2Msg.h @@ -0,0 +1,64 @@ +/**************************************************************** + * 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_FORUMV2_MSG_DIALOG_H +#define _CREATE_FORUMV2_MSG_DIALOG_H + +#include "ui_CreateForumV2Msg.h" + +class CreateForumV2Msg : public QMainWindow +{ + Q_OBJECT + +public: + CreateForumV2Msg(std::string fId, std::string pId); + + void newMsg(); /* cleanup */ + +private slots: + /** Create the context popup menu and it's submenus */ + void forumMessageCostumPopupMenu( QPoint point ); + + void fileHashingFinished(QList hashedFiles); + /* actions to take.... */ + void createMsg(); + void cancelMsg(); + void pasteLink(); + void pasteLinkFull(); + + void smileyWidgetForums(); + void addSmileys(); + void addFile(); + +protected: + void closeEvent (QCloseEvent * event); + +private: + std::string mForumId; + std::string mParentId; + + /** Qt Designer generated object */ + Ui::CreateForumV2Msg ui; +}; + +#endif + diff --git a/retroshare-gui/src/gui/forumsv2/CreateForumV2Msg.ui b/retroshare-gui/src/gui/forumsv2/CreateForumV2Msg.ui new file mode 100644 index 000000000..a9ce1bf29 --- /dev/null +++ b/retroshare-gui/src/gui/forumsv2/CreateForumV2Msg.ui @@ -0,0 +1,333 @@ + + + CreateForumV2Msg + + + Qt::NonModal + + + + 0 + 0 + 482 + 448 + + + + Post Forum Message + + + + :/images/rstray3.png:/images/rstray3.png + + + QToolBar#toolBar{background-image: url(:/images/connect/connectFriendBanner.png)} + + + Qt::ToolButtonTextUnderIcon + + + + + 0 + + + 0 + + + + + + + QFrame::NoFrame + + + QFrame::Raised + + + + 6 + + + 6 + + + + + + + Forum + + + + + + + false + + + + + + + + + + + Subject + + + + + + + + + + + + + + + + 16777215 + 38 + + + + QFrame#frame_2{ +background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, +stop:0 #FEFEFE, stop:1 #E8E8E8); + +border: 1px solid #CCCCCC;} + + + QFrame::Raised + + + + 6 + + + + + Qt::NoFocus + + + Attach File + + + + + + + :/images/add-share24.png:/images/add-share24.png + + + + 24 + 24 + + + + true + + + + + + + Qt::NoFocus + + + + + + + :/images/emoticons/kopete/kopete020.png:/images/emoticons/kopete/kopete020.png + + + + 24 + 24 + + + + true + + + + + + + Qt::NoFocus + + + Sign Message + + + + :/images/pgp.png:/images/pgp.png + + + + 24 + 24 + + + + true + + + + + + + Qt::Horizontal + + + + 40 + 15 + + + + + + + + Qt::NoFocus + + + Paste RetroShare Link + + + + + + + :/images/pasterslink.png:/images/pasterslink.png + + + true + + + + + + + + + + QFrame::NoFrame + + + QFrame::Raised + + + + 6 + + + 6 + + + + + Forum Post + + + + + + Qt::CustomContextMenu + + + <!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="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"></p></body></html> + + + + + + + + + + Attach files via drag and drop + + + + + + + 0 + 0 + + + + You can attach files via drag and drop here in this window + + + true + + + + + + + + + + + + + + + + toolBar + + + TopToolBarArea + + + false + + + + + + + + :/images/mail_send24.png:/images/mail_send24.png + + + Post Forum Msg + + + + + + :/images/button_cancel.png:/images/button_cancel.png + + + Close + + + + + + HashBox + QScrollArea +
gui/common/HashBox.h
+ 1 +
+
+ + + + +
diff --git a/retroshare-gui/src/gui/forumsv2/EditForumV2Details.cpp b/retroshare-gui/src/gui/forumsv2/EditForumV2Details.cpp new file mode 100644 index 000000000..1be2b5a85 --- /dev/null +++ b/retroshare-gui/src/gui/forumsv2/EditForumV2Details.cpp @@ -0,0 +1,81 @@ +/**************************************************************** + * RetroShare is distributed under the following license: + * + * Copyright (C) 2010 RetroShare Team + * + * 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 "EditForumV2Details.h" + +#include + +#include "util/misc.h" + +#include +#include +#include + + +/** Default constructor */ +EditForumV2Details::EditForumV2Details(std::string forumId, QWidget *parent, Qt::WFlags flags) + : QDialog(parent, flags), m_forumId(forumId) +{ + /* Invoke Qt Designer generated QObject setup routine */ + ui.setupUi(this); + + connect(ui.applyButton, SIGNAL(clicked()), this, SLOT(applyDialog())); + + loadForum(); +} + +void EditForumV2Details::loadForum() +{ + if (!rsForums) { + return; + } + + ForumInfo info; + rsForums->getForumInfo(m_forumId, info); + + // set name + ui.nameline->setText(QString::fromStdWString(info.forumName)); + + // set description + ui.DescriptiontextEdit->setText(QString::fromStdWString(info.forumDesc)); +} + +void EditForumV2Details::applyDialog() +{ + if (!rsForums) { + return; + } + + // if text boxes have not been edited leave alone + if (!ui.nameline->isModified() && !ui.DescriptiontextEdit->document()->isModified()) { + return; + } + + ForumInfo info; + + info.forumName = misc::removeNewLine(ui.nameline->text()).toStdWString(); + info.forumDesc = ui.DescriptiontextEdit->document()->toPlainText().toStdWString(); + + rsForums->setForumInfo(m_forumId, info); + + /* close the Dialog after the Changes applied */ + close(); +} diff --git a/retroshare-gui/src/gui/forumsv2/EditForumV2Details.h b/retroshare-gui/src/gui/forumsv2/EditForumV2Details.h new file mode 100644 index 000000000..55c9c2bc7 --- /dev/null +++ b/retroshare-gui/src/gui/forumsv2/EditForumV2Details.h @@ -0,0 +1,53 @@ +/**************************************************************** + * RetroShare is distributed under the following license: + * + * Copyright (C) 2010 RetroShare Team + * + * 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 _EDITFORUMV2DETAILS_H +#define _EDITFORUMV2DETAILS_H + +#include + +#include "ui_EditForumV2Details.h" + +class EditForumV2Details : public QDialog +{ + Q_OBJECT + +public: + /** Default constructor */ + EditForumV2Details(std::string forumId = "", QWidget *parent = 0, Qt::WFlags flags = 0); + +signals: + void configChanged(); + +private slots: + void applyDialog(); + +private: + void loadForum(); + + std::string m_forumId; + + /** Qt Designer generated object */ + Ui::EditForumV2Details ui; +}; + +#endif + diff --git a/retroshare-gui/src/gui/forumsv2/EditForumV2Details.ui b/retroshare-gui/src/gui/forumsv2/EditForumV2Details.ui new file mode 100644 index 000000000..b32810506 --- /dev/null +++ b/retroshare-gui/src/gui/forumsv2/EditForumV2Details.ui @@ -0,0 +1,130 @@ + + + EditForumV2Details + + + + 0 + 0 + 436 + 355 + + + + Forum Details + + + + :/images/rstray3.png:/images/rstray3.png + + + + + + + + Qt::Horizontal + + + + 311 + 20 + + + + + + + + Cancel + + + + + + + OK + + + false + + + true + + + + + + + + + 0 + + + + + :/images/info16.png:/images/info16.png + + + Edit Forum Details + + + + + + Forum Info + + + + + + Forum Name + + + + + + + + + + Forum Description + + + + + + + + + + + + + + + + + + + + + + + cancelButton + clicked() + EditForumDetails + close() + + + 307 + 333 + + + 217 + 177 + + + + + diff --git a/retroshare-gui/src/gui/forumsv2/ForumV2Details.cpp b/retroshare-gui/src/gui/forumsv2/ForumV2Details.cpp new file mode 100644 index 000000000..2cf05ff4f --- /dev/null +++ b/retroshare-gui/src/gui/forumsv2/ForumV2Details.cpp @@ -0,0 +1,143 @@ +/**************************************************************** + * RetroShare is distributed under the following license: + * + * Copyright (C) 2009 RetroShare Team + * + * 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 "ForumV2Details.h" + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + + +/* Define the format used for displaying the date and time */ +#define DATETIME_FMT "MMM dd hh:mm:ss" + +/** Default constructor */ +ForumV2Details::ForumV2Details(QWidget *parent, Qt::WFlags flags) + : QDialog(parent, flags) +{ + /* Invoke Qt Designer generated QObject setup routine */ + ui.setupUi(this); + + connect(ui.applyButton, SIGNAL(clicked()), this, SLOT(applyDialog())); + connect(ui.cancelButton, SIGNAL(clicked()), this, SLOT(closeinfodlg())); + + ui.applyButton->setToolTip(tr("Apply and Close")); + + ui.nameline ->setReadOnly(true); + ui.popline ->setReadOnly(true); + ui.postline ->setReadOnly(true); + ui.IDline ->setReadOnly(true); + ui.DescriptiontextEdit ->setReadOnly(true); + + ui.radioButton_authd->setEnabled(false); + ui.radioButton_anonymous->setEnabled(false); +} + + +/** + Overloads the default show() slot so we can set opacity*/ + +void +ForumV2Details::show() +{ + //loadSettings(); + if(!this->isVisible()) { + QDialog::show(); + + } +} + +void ForumV2Details::closeEvent (QCloseEvent * event) +{ + QWidget::closeEvent(event); +} + +void ForumV2Details::closeinfodlg() +{ + close(); +} + +void ForumV2Details::showDetails(std::string mCurrForumId) +{ + fId = mCurrForumId; + loadDialog(); +} + +void ForumV2Details::loadDialog() +{ + if (!rsForums) + { + return; + } + + ForumInfo fi; + rsForums->getForumInfo(fId, fi); + + // Set Forum Name + ui.nameline->setText(QString::fromStdWString(fi.forumName)); + + // Set Popularity + ui.popline->setText(QString::number(fi.pop)); + + // Set Last Post Date + if (fi.lastPost) { + QDateTime qtime; + qtime.setTime_t(fi.lastPost); + QString timestamp = qtime.toString("yyyy-MM-dd hh:mm:ss"); + ui.postline->setText(timestamp); + } + + // Set Forum ID + ui.IDline->setText(QString::fromStdString(fi.forumId)); + + // Set Forum Description + ui.DescriptiontextEdit->setText(QString::fromStdWString(fi.forumDesc)); + + if (fi.forumFlags & RS_DISTRIB_AUTHEN_REQ) + { + ui.radioButton_authd->setChecked(true); + ui.radioButton_anonymous->setChecked(false); + } + if (fi.forumFlags & RS_DISTRIB_AUTHEN_ANON) + { + ui.radioButton_authd->setChecked(false); + ui.radioButton_anonymous->setChecked(true); + } +} + +void ForumV2Details::applyDialog() +{ + + /* reload now */ + loadDialog(); + + /* close the Dialog after the Changes applied */ + closeinfodlg(); + +} diff --git a/retroshare-gui/src/gui/forumsv2/ForumV2Details.h b/retroshare-gui/src/gui/forumsv2/ForumV2Details.h new file mode 100644 index 000000000..3489fb344 --- /dev/null +++ b/retroshare-gui/src/gui/forumsv2/ForumV2Details.h @@ -0,0 +1,67 @@ +/**************************************************************** + * RetroShare is distributed under the following license: + * + * Copyright (C) 2009 RetroShare Team + * + * 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 _FORUMV2DETAILS_H +#define _FORUMV2DETAILS_H + +#include + +#include "ui_ForumV2Details.h" + +class ForumV2Details : public QDialog +{ + Q_OBJECT + + public: + + /** Default constructor */ + ForumV2Details(QWidget *parent = 0, Qt::WFlags flags = 0); + /** Default destructor */ + + void showDetails(std::string mCurrForumId); + +signals: + void configChanged() ; + +public slots: + /** Overloaded QWidget.show */ + void show(); + +protected: + void closeEvent (QCloseEvent * event); + +private slots: + + void closeinfodlg(); + void applyDialog(); + +private: + + void loadDialog(); + + std::string fId; + /** Qt Designer generated object */ + Ui::ForumV2Details ui; + +}; + +#endif + diff --git a/retroshare-gui/src/gui/forumsv2/ForumV2Details.ui b/retroshare-gui/src/gui/forumsv2/ForumV2Details.ui new file mode 100644 index 000000000..9662916c7 --- /dev/null +++ b/retroshare-gui/src/gui/forumsv2/ForumV2Details.ui @@ -0,0 +1,201 @@ + + + ForumV2Details + + + + 0 + 0 + 436 + 355 + + + + Forum Details + + + + :/images/rstray3.png:/images/rstray3.png + + + + + + 0 + + + + + :/images/info16.png:/images/info16.png + + + Forum Details + + + + + + Forum Info + + + + + + Forum Name + + + + + + + + + + Popularity + + + + + + + true + + + + + + + Last Post + + + + + + + true + + + + + + + Forum ID + + + + + + + + + + Forum Description + + + + + + + + + + + + + + + + + :/images/encrypted22.png:/images/encrypted22.png + + + Security + + + + + + Allowed Messages + + + + + + Authemticated Messages + + + + + + + Anonymous Messages + + + true + + + + + + + + + + Qt::Vertical + + + + 358 + 172 + + + + + + + + + + + + + + Qt::Horizontal + + + + 311 + 20 + + + + + + + + Cancel + + + + + + + OK + + + false + + + true + + + + + + + + + + + + diff --git a/retroshare-gui/src/gui/unfinished/ApplicationWindow.cpp b/retroshare-gui/src/gui/unfinished/ApplicationWindow.cpp index a9fb6dadf..4bad1ffcd 100644 --- a/retroshare-gui/src/gui/unfinished/ApplicationWindow.cpp +++ b/retroshare-gui/src/gui/unfinished/ApplicationWindow.cpp @@ -36,6 +36,7 @@ #include "gui/WikiPoos/WikiDialog.h" #include "gui/TheWire/WireDialog.h" #include "gui/Identity/IdDialog.h" +#include "gui/ForumsV2Dialog.h" //#include "GamesDialog.h" //#include "CalDialog.h" @@ -55,7 +56,7 @@ #define IMAGE_CALENDAR ":/images/calendar.png" #define IMAGE_LIBRARY ":/images/library.png" #define IMAGE_PLUGINS ":/images/extension_32.png" - +#define IMAGE_FORUMSV2 ":/images/konversation.png" /** Constructor */ ApplicationWindow::ApplicationWindow(QWidget* parent, Qt::WFlags flags) @@ -91,7 +92,6 @@ ApplicationWindow::ApplicationWindow(QWidget* parent, Qt::WFlags flags) //ui.stackPages->add(calDialog = new CalDialog(ui.stackPages), // createPageAction(QIcon(IMAGE_CALENDAR), tr("Shared Calendars"), grp)); - IdDialog *idDialog = NULL; ui.stackPages->add(idDialog = new IdDialog(ui.stackPages), createPageAction(QIcon(IMAGE_LIBRARY), tr("Identities"), grp)); @@ -108,6 +108,10 @@ ApplicationWindow::ApplicationWindow(QWidget* parent, Qt::WFlags flags) ui.stackPages->add(wireDialog = new WireDialog(ui.stackPages), createPageAction(QIcon(IMAGE_BWGRAPH), tr("The Wire"), grp)); + ForumsV2Dialog *forumsV2Dialog = NULL; + ui.stackPages->add(forumsV2Dialog = new ForumsV2Dialog(ui.stackPages), + createPageAction(QIcon(IMAGE_FORUMSV2), tr("ForumsV2"), grp)); + /* Create the toolbar */ ui.toolBar->addActions(grp->actions()); ui.toolBar->addSeparator(); @@ -142,7 +146,7 @@ void ApplicationWindow::show() QMainWindow::show(); } else { QMainWindow::activateWindow(); - setWindowState(windowState() & ~Qt::WindowMinimized | Qt::WindowActive); + setWindowState(windowState() & (~Qt::WindowMinimized | Qt::WindowActive)); QMainWindow::raise(); } } diff --git a/retroshare-gui/src/util/TokenQueue.cpp b/retroshare-gui/src/util/TokenQueue.cpp index ab48929ee..232e17bb4 100644 --- a/retroshare-gui/src/util/TokenQueue.cpp +++ b/retroshare-gui/src/util/TokenQueue.cpp @@ -34,54 +34,49 @@ TokenQueue::TokenQueue(RsTokenService *service, TokenResponse *resp) :QWidget(NULL), mService(service), mResponder(resp) { - //mTrigger = new QTimer(this); - //mTrigger->connect(mTrigger, SIGNAL(timeout()), this, SLOT(pollRequests())); return; } -bool TokenQueue::genericRequest(uint32_t basictype, const RsTokReqOptions &opts, std::list ids, uint32_t usertype) +bool TokenQueue::requestGroupInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptions &opts, std::list ids, uint32_t usertype) { - uint32_t token; - switch(basictype) - { - case TOKENREQ_GROUPLIST: - mService->requestGroupList(token, opts); - break; - - case TOKENREQ_GROUPDATA: - mService->requestGroupData(token, ids); - break; - - case TOKENREQ_MSGLIST: - mService->requestMsgList(token, opts, ids); - break; - - case TOKENREQ_MSGRELATEDLIST: - mService->requestMsgRelatedList(token, opts, ids); - break; - - case TOKENREQ_MSGDATA: - mService->requestMsgData(token, ids); - break; - - default: - return false; - } - - queueRequest(token, basictype, usertype); + uint32_t basictype = TOKENREQ_GROUPINFO; + mService->requestGroupInfo(token, anstype, opts, ids); + queueRequest(token, basictype, anstype, usertype); return true; } -void TokenQueue::queueRequest(uint32_t token, uint32_t basictype, uint32_t usertype) +bool TokenQueue::requestMsgInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptions &opts, std::list ids, uint32_t usertype) { - std::cerr << "TokenQueue::queueRequest() Token: " << token << " Type: " << basictype << " UserType: " << usertype; + uint32_t basictype = TOKENREQ_MSGINFO; + mService->requestMsgInfo(token, anstype, opts, ids); + queueRequest(token, basictype, anstype, usertype); + + return true; +} + + +bool TokenQueue::requestMsgRelatedInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptions &opts, std::list ids, uint32_t usertype) +{ + uint32_t basictype = TOKENREQ_MSGRELATEDINFO; + mService->requestMsgRelatedInfo(token, anstype, opts, ids); + queueRequest(token, basictype, anstype, usertype); + + return true; +} + + +void TokenQueue::queueRequest(uint32_t token, uint32_t basictype, uint32_t anstype, uint32_t usertype) +{ + std::cerr << "TokenQueue::queueRequest() Token: " << token << " Type: " << basictype; + std::cerr << " AnsType: " << anstype << " UserType: " << usertype; std::cerr << std::endl; TokenRequest req; req.mToken = token; req.mType = basictype; + req.mAnsType = anstype; req.mUserType = usertype; gettimeofday(&req.mRequestTs, NULL); @@ -143,9 +138,9 @@ bool TokenQueue::checkForRequest(uint32_t token) void TokenQueue::loadRequest(const TokenRequest &req) { - std::cerr << "TokenQueue::loadRequest() Dummy Function - please Implement"; - std::cerr << std::endl; - std::cerr << "Token: " << req.mToken << " Type: " << req.mType << " UserType: " << req.mUserType; + std::cerr << "TokenQueue::loadRequest(): "; + std::cerr << "Token: " << req.mToken << " Type: " << req.mType; + std::cerr << " AnsType: " << req.mAnsType << " UserType: " << req.mUserType; std::cerr << std::endl; mResponder->loadRequest(this, req); @@ -154,6 +149,32 @@ void TokenQueue::loadRequest(const TokenRequest &req) } +bool TokenQueue::cancelRequest(const uint32_t token) +{ + /* cancel at lower level first */ + mService->cancelRequest(token); + + std::list::iterator it; + + for(it = mRequests.begin(); it != mRequests.end(); it++) + { + if (it->mToken == token) + { + mRequests.erase(it); + + std::cerr << "TokenQueue::cancelRequest() Cleared Request: " << token; + std::cerr << std::endl; + + return true; + } + } + + std::cerr << "TokenQueue::cancelRequest() Failed to Find Request: " << token; + std::cerr << std::endl; + + return false; +} + diff --git a/retroshare-gui/src/util/TokenQueue.h b/retroshare-gui/src/util/TokenQueue.h index b3addc8f7..7a09ca806 100644 --- a/retroshare-gui/src/util/TokenQueue.h +++ b/retroshare-gui/src/util/TokenQueue.h @@ -35,13 +35,9 @@ #define COMPLETED_REQUEST 4 - -#define TOKENREQ_GROUPLIST 1 -#define TOKENREQ_GROUPDATA 2 -#define TOKENREQ_MSGLIST 3 -#define TOKENREQ_MSGRELATEDLIST 4 -#define TOKENREQ_MSGDATA 5 - +#define TOKENREQ_GROUPINFO 1 +#define TOKENREQ_MSGINFO 2 +#define TOKENREQ_MSGRELATEDINFO 3 class TokenQueue; @@ -50,6 +46,7 @@ class TokenRequest public: uint32_t mToken; uint32_t mType; + uint32_t mAnsType; uint32_t mUserType; struct timeval mRequestTs; struct timeval mPollTs; @@ -72,8 +69,15 @@ public: TokenQueue(RsTokenService *service, TokenResponse *resp); /* generic handling of token / response update behaviour */ - bool genericRequest(uint32_t basictype, const RsTokReqOptions &opt, std::list ids, uint32_t usertype); - void queueRequest(uint32_t token, uint32_t basictype, uint32_t usertype); + bool requestGroupInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptions &opts, + std::list ids, uint32_t usertype); + bool requestMsgInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptions &opts, + std::list ids, uint32_t usertype); + bool requestMsgRelatedInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptions &opts, + std::list ids, uint32_t usertype); + bool cancelRequest(const uint32_t token); + + void queueRequest(uint32_t token, uint32_t basictype, uint32_t anstype, uint32_t usertype); bool checkForRequest(uint32_t token); void loadRequest(const TokenRequest &req); @@ -95,3 +99,4 @@ private: #endif +