From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- comm/mailnews/base/src/nsSubscribableServer.cpp | 867 ++++++++++++++++++++++++ 1 file changed, 867 insertions(+) create mode 100644 comm/mailnews/base/src/nsSubscribableServer.cpp (limited to 'comm/mailnews/base/src/nsSubscribableServer.cpp') diff --git a/comm/mailnews/base/src/nsSubscribableServer.cpp b/comm/mailnews/base/src/nsSubscribableServer.cpp new file mode 100644 index 0000000000..043ef2e4d3 --- /dev/null +++ b/comm/mailnews/base/src/nsSubscribableServer.cpp @@ -0,0 +1,867 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsSubscribableServer.h" +#include "nsIMsgIncomingServer.h" +#include "nsIServiceManager.h" +#include "nsMsgI18N.h" +#include "nsMsgUtils.h" +#include "nsServiceManagerUtils.h" +#include "nsTreeColumns.h" +#include "mozilla/dom/DataTransfer.h" + +/** + * The basic structure for the tree of the implementation. + * + * These elements are stored in reverse alphabetical order. + * Each node owns its children and subsequent siblings. + */ +struct SubscribeTreeNode { + nsCString name; + nsCString path; + bool isSubscribed; + SubscribeTreeNode* prevSibling; + SubscribeTreeNode* nextSibling; + SubscribeTreeNode* firstChild; + SubscribeTreeNode* lastChild; + SubscribeTreeNode* parent; + // Stores the child considered most likely to be next searched for - usually + // the most recently-added child. If names match the search can early-out. + SubscribeTreeNode* cachedChild; + bool isSubscribable; + bool isOpen; +}; + +nsSubscribableServer::nsSubscribableServer(void) { + mDelimiter = '.'; + mShowFullName = true; + mTreeRoot = nullptr; + mStopped = false; +} + +nsresult nsSubscribableServer::Init() { return NS_OK; } + +nsSubscribableServer::~nsSubscribableServer(void) { + FreeRows(); + if (mTreeRoot) { + FreeSubtree(mTreeRoot); + } +} + +NS_IMPL_ISUPPORTS(nsSubscribableServer, nsISubscribableServer, nsITreeView) + +NS_IMETHODIMP +nsSubscribableServer::SetIncomingServer(nsIMsgIncomingServer* aServer) { + if (!aServer) { + mIncomingServerUri.AssignLiteral(""); + mServerType.Truncate(); + return NS_OK; + } + aServer->GetType(mServerType); + + // We intentionally do not store a pointer to the aServer here + // as it would create reference loops, because nsIImapIncomingServer + // and nsINntpIncomingServer keep a reference to an internal + // nsISubscribableServer object. + // We only need the URI of the server anyway. + return aServer->GetServerURI(mIncomingServerUri); +} + +NS_IMETHODIMP +nsSubscribableServer::GetDelimiter(char* aDelimiter) { + NS_ENSURE_ARG_POINTER(aDelimiter); + *aDelimiter = mDelimiter; + return NS_OK; +} + +NS_IMETHODIMP +nsSubscribableServer::SetDelimiter(char aDelimiter) { + mDelimiter = aDelimiter; + return NS_OK; +} + +NS_IMETHODIMP +nsSubscribableServer::SetAsSubscribed(const nsACString& path) { + nsresult rv = NS_OK; + + SubscribeTreeNode* node = nullptr; + rv = FindAndCreateNode(path, &node); + NS_ENSURE_SUCCESS(rv, rv); + + NS_ASSERTION(node, "didn't find the node"); + if (!node) return NS_ERROR_FAILURE; + node->isSubscribable = true; + node->isSubscribed = true; + + return rv; +} + +NS_IMETHODIMP +nsSubscribableServer::AddTo(const nsACString& aName, bool aAddAsSubscribed, + bool aSubscribable, bool aChangeIfExists) { + nsresult rv = NS_OK; + + if (mStopped) { + return NS_ERROR_FAILURE; + } + + SubscribeTreeNode* node = nullptr; + + // todo, shouldn't we pass in aAddAsSubscribed, for the + // default value if we create it? + rv = FindAndCreateNode(aName, &node); + NS_ENSURE_SUCCESS(rv, rv); + NS_ASSERTION(node, "didn't find the node"); + if (!node) return NS_ERROR_FAILURE; + + if (aChangeIfExists) { + node->isSubscribed = aAddAsSubscribed; + } + + node->isSubscribable = aSubscribable; + + return NS_OK; +} + +NS_IMETHODIMP +nsSubscribableServer::SetState(const nsACString& aPath, bool aState, + bool* aStateChanged) { + nsresult rv = NS_OK; + NS_ASSERTION(!aPath.IsEmpty() && aStateChanged, "no path or stateChanged"); + if (aPath.IsEmpty() || !aStateChanged) return NS_ERROR_NULL_POINTER; + + NS_ASSERTION(mozilla::IsUtf8(aPath), "aPath is not in UTF-8"); + + *aStateChanged = false; + + SubscribeTreeNode* node = nullptr; + rv = FindAndCreateNode(aPath, &node); + NS_ENSURE_SUCCESS(rv, rv); + + NS_ASSERTION(node, "didn't find the node"); + if (!node) return NS_ERROR_FAILURE; + + NS_ASSERTION(node->isSubscribable, "fix this"); + if (!node->isSubscribable) { + return NS_OK; + } + + if (node->isSubscribed == aState) { + return NS_OK; + } else { + node->isSubscribed = aState; + *aStateChanged = true; + + // Repaint the tree row to show/clear the check mark. + if (mTree) { + bool dummy; + int32_t index = GetRow(node, &dummy); + if (index >= 0) mTree->InvalidateRow(index); + } + } + return NS_OK; +} + +NS_IMETHODIMP +nsSubscribableServer::SetSubscribeListener(nsISubscribeListener* aListener) { + mSubscribeListener = aListener; + return NS_OK; +} + +NS_IMETHODIMP +nsSubscribableServer::GetSubscribeListener(nsISubscribeListener** aListener) { + NS_ENSURE_ARG_POINTER(aListener); + NS_IF_ADDREF(*aListener = mSubscribeListener); + return NS_OK; +} + +NS_IMETHODIMP +nsSubscribableServer::SubscribeCleanup() { + NS_ASSERTION(false, "override this."); + return NS_ERROR_FAILURE; +} + +NS_IMETHODIMP +nsSubscribableServer::StartPopulatingWithUri(nsIMsgWindow* aMsgWindow, + bool aForceToServer, + const nsACString& uri) { + mStopped = false; + return NS_OK; +} + +NS_IMETHODIMP +nsSubscribableServer::StartPopulating(nsIMsgWindow* aMsgWindow, + bool aForceToServer, + bool aGetOnlyNew /*ignored*/) { + mStopped = false; + + FreeRows(); + if (mTreeRoot) { + FreeSubtree(mTreeRoot); + mTreeRoot = nullptr; + } + return NS_OK; +} + +NS_IMETHODIMP +nsSubscribableServer::StopPopulating(nsIMsgWindow* aMsgWindow) { + mStopped = true; + + FreeRows(); + + if (mTreeRoot) { + SubscribeTreeNode* node = mTreeRoot->lastChild; + // Add top level items as closed. + while (node) { + node->isOpen = false; + mRowMap.AppendElement(node); + node = node->prevSibling; + } + + // Invalidate the whole thing. + if (mTree) mTree->RowCountChanged(0, mRowMap.Length()); + + // Open all the top level items if they are containers. + uint32_t topRows = mRowMap.Length(); + for (int32_t i = topRows - 1; i >= 0; i--) { + bool isContainer = false; + IsContainer(i, &isContainer); + if (isContainer) ToggleOpenState(i); + } + } + + if (mSubscribeListener) mSubscribeListener->OnDonePopulating(); + + return NS_OK; +} + +NS_IMETHODIMP +nsSubscribableServer::UpdateSubscribed() { + NS_ASSERTION(false, "override this."); + return NS_ERROR_FAILURE; +} + +NS_IMETHODIMP +nsSubscribableServer::Subscribe(const char16_t* aName) { + NS_ASSERTION(false, "override this."); + return NS_ERROR_FAILURE; +} + +NS_IMETHODIMP +nsSubscribableServer::Unsubscribe(const char16_t* aName) { + NS_ASSERTION(false, "override this."); + return NS_ERROR_FAILURE; +} + +NS_IMETHODIMP +nsSubscribableServer::SetShowFullName(bool showFullName) { + mShowFullName = showFullName; + return NS_OK; +} + +void nsSubscribableServer::FreeSubtree(SubscribeTreeNode* node) { + // NOTE: this doesn't cleanly detach each node, but that's not an issue + // here. This is a nuking, not a surgical removal. + + // recursively free the children + if (node->firstChild) { + // will free node->firstChild + FreeSubtree(node->firstChild); + node->firstChild = nullptr; + } + + // recursively free the siblings + if (node->nextSibling) { + FreeSubtree(node->nextSibling); + node->nextSibling = nullptr; + } + + delete node; +} + +void nsSubscribableServer::FreeRows() { + int32_t rowCount = mRowMap.Length(); + mRowMap.Clear(); + if (mTree) mTree->RowCountChanged(0, -rowCount); +} + +SubscribeTreeNode* nsSubscribableServer::CreateNode(SubscribeTreeNode* parent, + nsACString const& name, + nsACString const& path) { + SubscribeTreeNode* node = new SubscribeTreeNode(); + + node->name.Assign(name); + node->path.Assign(path); + node->parent = parent; + node->prevSibling = nullptr; + node->nextSibling = nullptr; + node->firstChild = nullptr; + node->lastChild = nullptr; + node->isSubscribed = false; + node->isSubscribable = false; + node->isOpen = true; + node->cachedChild = nullptr; + if (parent) { + parent->cachedChild = node; + } + return node; +} + +nsresult nsSubscribableServer::AddChildNode(SubscribeTreeNode* parent, + nsACString const& name, + const nsACString& path, + SubscribeTreeNode** child) { + nsresult rv = NS_OK; + NS_ASSERTION(parent && child && !name.IsEmpty() && !path.IsEmpty(), + "parent, child or name is null"); + if (!parent || !child || name.IsEmpty() || path.IsEmpty()) + return NS_ERROR_NULL_POINTER; + + // Adding to a node with no children? + if (!parent->firstChild) { + // CreateNode will set the parent->cachedChild + *child = CreateNode(parent, name, path); + parent->firstChild = *child; + parent->lastChild = *child; + return NS_OK; + } + + // Did we just add a child of this name? + if (parent->cachedChild) { + if (parent->cachedChild->name.Equals(name)) { + *child = parent->cachedChild; + return NS_OK; + } + } + + SubscribeTreeNode* current = parent->firstChild; + + /* + * Insert in reverse alphabetical order. + * This will reduce the # of strcmps since this is faster assuming: + * 1) the hostinfo.dat feeds us the groups in alphabetical order + * since we control the hostinfo.dat file, we can guarantee this. + * 2) the server gives us the groups in alphabetical order + * we can't guarantee this, but it seems to be a common thing. + * + * Because we have firstChild, lastChild, nextSibling, prevSibling, + * we can efficiently reverse the order when dumping to hostinfo.dat + * or to GetTargets(). + */ + int32_t compare = Compare(current->name, name); + + while (current && (compare != 0)) { + if (compare < 0) { + // CreateNode will set the parent->cachedChild + *child = CreateNode(parent, name, path); + NS_ENSURE_SUCCESS(rv, rv); + + (*child)->nextSibling = current; + (*child)->prevSibling = current->prevSibling; + current->prevSibling = (*child); + if (!(*child)->prevSibling) { + parent->firstChild = (*child); + } else { + (*child)->prevSibling->nextSibling = (*child); + } + + return NS_OK; + } + current = current->nextSibling; + if (current) { + NS_ASSERTION(!current->name.IsEmpty(), "no name!"); + compare = Compare(current->name, name); + } else { + compare = -1; // anything but 0, since that would be a match + } + } + + if (compare == 0) { + // already exists; + *child = current; + parent->cachedChild = *child; + return NS_OK; + } + + // CreateNode will set the parent->cachedChild + *child = CreateNode(parent, name, path); + + (*child)->prevSibling = parent->lastChild; + (*child)->nextSibling = nullptr; + parent->lastChild->nextSibling = *child; + parent->lastChild = *child; + + return NS_OK; +} + +nsresult nsSubscribableServer::FindAndCreateNode(const nsACString& aPath, + SubscribeTreeNode** aResult) { + nsresult rv = NS_OK; + NS_ASSERTION(aResult, "no result"); + NS_ENSURE_ARG_POINTER(aResult); + + if (!mTreeRoot) { + // the root has no parent, and its name is server uri + mTreeRoot = CreateNode(nullptr, mIncomingServerUri, EmptyCString()); + } + + if (aPath.IsEmpty()) { + *aResult = mTreeRoot; + return NS_OK; + } + + *aResult = nullptr; + + SubscribeTreeNode* parent = mTreeRoot; + SubscribeTreeNode* child = nullptr; + + uint32_t tokenStart = 0; + // Special case paths that start with the hierarchy delimiter. + // We want to include that delimiter in the first token name. + // So start from position 1. + int32_t tokenEnd = aPath.FindChar(mDelimiter, tokenStart + 1); + while (true) { + if (tokenEnd == kNotFound) { + if (tokenStart >= aPath.Length()) break; + tokenEnd = aPath.Length(); + } + nsCString token(Substring(aPath, tokenStart, tokenEnd - tokenStart)); + rv = AddChildNode(parent, token, Substring(aPath, 0, tokenEnd), &child); + if (NS_FAILED(rv)) return rv; + tokenStart = tokenEnd + 1; + tokenEnd = aPath.FindChar(mDelimiter, tokenStart); + parent = child; + } + + // the last child we add is the result + *aResult = child; + return rv; +} + +NS_IMETHODIMP +nsSubscribableServer::HasChildren(const nsACString& aPath, bool* aHasChildren) { + NS_ASSERTION(aHasChildren, "no hasChildren"); + NS_ENSURE_ARG_POINTER(aHasChildren); + + *aHasChildren = false; + + SubscribeTreeNode* node = nullptr; + nsresult rv = FindAndCreateNode(aPath, &node); + NS_ENSURE_SUCCESS(rv, rv); + + NS_ASSERTION(node, "didn't find the node"); + if (!node) return NS_ERROR_FAILURE; + + *aHasChildren = (node->firstChild != nullptr); + return NS_OK; +} + +NS_IMETHODIMP +nsSubscribableServer::IsSubscribed(const nsACString& aPath, + bool* aIsSubscribed) { + NS_ENSURE_ARG_POINTER(aIsSubscribed); + + *aIsSubscribed = false; + + SubscribeTreeNode* node = nullptr; + nsresult rv = FindAndCreateNode(aPath, &node); + NS_ENSURE_SUCCESS(rv, rv); + + NS_ASSERTION(node, "didn't find the node"); + if (!node) return NS_ERROR_FAILURE; + + *aIsSubscribed = node->isSubscribed; + return NS_OK; +} + +NS_IMETHODIMP +nsSubscribableServer::IsSubscribable(const nsACString& aPath, + bool* aIsSubscribable) { + NS_ENSURE_ARG_POINTER(aIsSubscribable); + + *aIsSubscribable = false; + + SubscribeTreeNode* node = nullptr; + nsresult rv = FindAndCreateNode(aPath, &node); + NS_ENSURE_SUCCESS(rv, rv); + + NS_ASSERTION(node, "didn't find the node"); + if (!node) return NS_ERROR_FAILURE; + + *aIsSubscribable = node->isSubscribable; + return NS_OK; +} + +NS_IMETHODIMP +nsSubscribableServer::GetLeafName(const nsACString& aPath, + nsAString& aLeafName) { + SubscribeTreeNode* node = nullptr; + nsresult rv = FindAndCreateNode(aPath, &node); + NS_ENSURE_SUCCESS(rv, rv); + + NS_ASSERTION(node, "didn't find the node"); + if (!node) return NS_ERROR_FAILURE; + + // XXX TODO FIXME + // I'm assuming that mShowFullName is true for NNTP, false for IMAP. + // For imap, the node name is in MUTF-7; for news, the path is escaped UTF-8. + // When we switch to using the tree, this hack will go away. + if (mShowFullName) { + return NS_MsgDecodeUnescapeURLPath(aPath, aLeafName); + } + + return CopyFolderNameToUTF16(node->name, aLeafName); +} + +NS_IMETHODIMP +nsSubscribableServer::GetFirstChildURI(const nsACString& aPath, + nsACString& aResult) { + aResult.Truncate(); + + SubscribeTreeNode* node = nullptr; + nsresult rv = FindAndCreateNode(aPath, &node); + NS_ENSURE_SUCCESS(rv, rv); + + NS_ASSERTION(node, "didn't find the node"); + if (!node) return NS_ERROR_FAILURE; + + // no children + if (!node->firstChild) return NS_ERROR_FAILURE; + + aResult.Assign(node->firstChild->path); + + return NS_OK; +} + +NS_IMETHODIMP +nsSubscribableServer::GetChildURIs(const nsACString& aPath, + nsTArray& aResult) { + aResult.Clear(); + SubscribeTreeNode* node = nullptr; + nsresult rv = FindAndCreateNode(aPath, &node); + NS_ENSURE_SUCCESS(rv, rv); + + NS_ASSERTION(node, "didn't find the node"); + if (!node) return NS_ERROR_FAILURE; + + NS_ASSERTION(mTreeRoot, "no tree root!"); + if (!mTreeRoot) return NS_ERROR_UNEXPECTED; + + // We inserted them in reverse alphabetical order. + // So pull them out in reverse to get the right order + // in the subscribe dialog. + SubscribeTreeNode* current = node->lastChild; + // return failure if there are no children. + if (!current) return NS_ERROR_FAILURE; + + while (current) { + NS_ASSERTION(!current->name.IsEmpty(), "no name"); + if (current->name.IsEmpty()) { + return NS_ERROR_FAILURE; + } + aResult.AppendElement(current->path); + current = current->prevSibling; + } + + return NS_OK; +} + +NS_IMETHODIMP +nsSubscribableServer::CommitSubscribeChanges() { + NS_ASSERTION(false, "override this."); + return NS_ERROR_FAILURE; +} + +NS_IMETHODIMP +nsSubscribableServer::SetSearchValue(const nsAString& aSearchValue) { + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsSubscribableServer::GetSupportsSubscribeSearch(bool* retVal) { + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsSubscribableServer::GetFolderView(nsITreeView** aView) { + NS_ENSURE_ARG_POINTER(aView); + return this->QueryInterface(NS_GET_IID(nsITreeView), (void**)aView); +} + +int32_t nsSubscribableServer::GetRow(SubscribeTreeNode* node, bool* open) { + int32_t parentRow = -1; + if (node->parent) parentRow = GetRow(node->parent, open); + + // If the parent wasn't opened, we're not in the row map + if (open && *open == false) return -1; + + if (open) *open = node->isOpen; + + for (uint32_t row = parentRow + 1; row < mRowMap.Length(); row++) { + if (mRowMap[row] == node) return row; + } + + // Apparently, we're not in the map + return -1; +} + +NS_IMETHODIMP +nsSubscribableServer::GetSelection(nsITreeSelection** selection) { + NS_IF_ADDREF(*selection = mSelection); + return NS_OK; +} + +NS_IMETHODIMP +nsSubscribableServer::SetSelection(nsITreeSelection* selection) { + mSelection = selection; + return NS_OK; +} + +NS_IMETHODIMP +nsSubscribableServer::GetRowCount(int32_t* rowCount) { + *rowCount = mRowMap.Length(); + return NS_OK; +} + +NS_IMETHODIMP +nsSubscribableServer::SetTree(mozilla::dom::XULTreeElement* aTree) { + mTree = aTree; + return NS_OK; +} + +NS_IMETHODIMP +nsSubscribableServer::IsContainer(int32_t aIndex, bool* retval) { + *retval = !!mRowMap[aIndex]->firstChild; + return NS_OK; +} + +NS_IMETHODIMP +nsSubscribableServer::IsContainerEmpty(int32_t aIndex, bool* retval) { + *retval = false; + return NS_OK; +} + +NS_IMETHODIMP +nsSubscribableServer::IsContainerOpen(int32_t aIndex, bool* retval) { + *retval = mRowMap[aIndex]->isOpen; + return NS_OK; +} + +NS_IMETHODIMP +nsSubscribableServer::GetParentIndex(int32_t aIndex, int32_t* retval) { + SubscribeTreeNode* parent = mRowMap[aIndex]->parent; + if (!parent) { + *retval = -1; + return NS_OK; + } + + int32_t index; + for (index = aIndex - 1; index >= 0; index--) { + if (mRowMap[index] == parent) { + *retval = index; + return NS_OK; + } + } + *retval = -1; + return NS_OK; +} + +NS_IMETHODIMP +nsSubscribableServer::HasNextSibling(int32_t aRowIndex, int32_t aAfterIndex, + bool* retval) { + // This looks odd, but is correct. Using ->nextSibling gives a bad tree. + *retval = !!mRowMap[aRowIndex]->prevSibling; + return NS_OK; +} + +NS_IMETHODIMP +nsSubscribableServer::GetLevel(int32_t aIndex, int32_t* retval) { + // When starting with -2, we increase twice and return 0 for a top level node. + int32_t level = -2; + SubscribeTreeNode* node = mRowMap[aIndex]; + while (node) { + node = node->parent; + level++; + } + + *retval = level; + return NS_OK; +} + +NS_IMETHODIMP +nsSubscribableServer::ToggleOpenState(int32_t aIndex) { + SubscribeTreeNode* node = mRowMap[aIndex]; + if (node->isOpen) { + node->isOpen = false; + + // Remove subtree by deleting elements from array up to next sibling. + int32_t count = 0; + do { + // Find next sibling or the beginning of the next subtree. + if (node->prevSibling) { + count = mRowMap.IndexOf(node->prevSibling, aIndex) - aIndex - 1; + } else { + node = node->parent; + // When node reaches the root, delete the rest of the array. + if (!node->parent) { + count = mRowMap.Length() - aIndex - 1; + } + } + } while (!count && node->parent); + mRowMap.RemoveElementsAt(aIndex + 1, count); + if (mTree) { + mTree->RowCountChanged(aIndex + 1, -count); + mTree->InvalidateRow(aIndex); + } + } else { + // Recursively add the children nodes (i.e., remember open) + node->isOpen = true; + int32_t total = 0; + node = node->lastChild; + while (node) { + total += AddSubtree(node, aIndex + 1 + total); + node = node->prevSibling; + } + if (mTree) { + mTree->RowCountChanged(aIndex + 1, total); + mTree->InvalidateRow(aIndex); + } + } + return NS_OK; +} + +int32_t nsSubscribableServer::AddSubtree(SubscribeTreeNode* node, + int32_t index) { + mRowMap.InsertElementAt(index, node); + int32_t total = 1; + if (node->isOpen) { + node = node->lastChild; + while (node) { + total += AddSubtree(node, index + total); + node = node->prevSibling; + } + } + return total; +} + +NS_IMETHODIMP +nsSubscribableServer::GetCellText(int32_t aRow, nsTreeColumn* aCol, + nsAString& retval) { + nsString colId; + aCol->GetId(colId); + if (colId.EqualsLiteral("nameColumn")) { + nsCString path(mRowMap[aRow]->path); + GetLeafName(path, retval); + } + return NS_OK; +} + +NS_IMETHODIMP +nsSubscribableServer::GetCellValue(int32_t aRow, nsTreeColumn* aCol, + nsAString& retval) { + nsString colId; + aCol->GetId(colId); + if (colId.EqualsLiteral("nameColumn")) + retval = NS_ConvertUTF8toUTF16(mRowMap[aRow]->path); + if (colId.EqualsLiteral("subscribedColumn")) { + retval = mRowMap[aRow]->isSubscribed ? u"true"_ns : u"false"_ns; + } + return NS_OK; +} + +NS_IMETHODIMP +nsSubscribableServer::SetCellText(int32_t aRow, nsTreeColumn* aCol, + const nsAString& aText) { + return NS_OK; +} + +NS_IMETHODIMP +nsSubscribableServer::SetCellValue(int32_t aRow, nsTreeColumn* aCol, + const nsAString& aText) { + return NS_OK; +} + +NS_IMETHODIMP +nsSubscribableServer::GetCellProperties(int32_t aRow, nsTreeColumn* aCol, + nsAString& aProps) { + SubscribeTreeNode* node = mRowMap[aRow]; + if (node->isSubscribable) + aProps.AssignLiteral("subscribable-true"); + else + aProps.AssignLiteral("subscribable-false"); + + nsString colId; + aCol->GetId(colId); + if (colId.EqualsLiteral("subscribedColumn")) { + if (node->isSubscribed) + aProps.AppendLiteral(" subscribed-true"); + else + aProps.AppendLiteral(" subscribed-false"); + } else if (colId.EqualsLiteral("nameColumn")) { + aProps.AppendLiteral(" serverType-"); + aProps.Append(NS_ConvertUTF8toUTF16(mServerType)); + } + return NS_OK; +} + +NS_IMETHODIMP +nsSubscribableServer::GetRowProperties(int32_t aRow, nsAString& aProps) { + return NS_OK; +} + +NS_IMETHODIMP +nsSubscribableServer::GetColumnProperties(nsTreeColumn* aCol, + nsAString& aProps) { + return NS_OK; +} + +NS_IMETHODIMP +nsSubscribableServer::IsEditable(int32_t aRow, nsTreeColumn* aCol, + bool* retval) { + *retval = false; + return NS_OK; +} + +NS_IMETHODIMP +nsSubscribableServer::IsSeparator(int32_t aRowIndex, bool* retval) { + *retval = false; + return NS_OK; +} + +NS_IMETHODIMP +nsSubscribableServer::IsSorted(bool* retval) { + *retval = false; + return NS_OK; +} + +NS_IMETHODIMP +nsSubscribableServer::CanDrop(int32_t aIndex, int32_t aOrientation, + mozilla::dom::DataTransfer* aData, bool* retval) { + *retval = false; + return NS_OK; +} + +NS_IMETHODIMP +nsSubscribableServer::Drop(int32_t aRow, int32_t aOrientation, + mozilla::dom::DataTransfer* aData) { + return NS_OK; +} + +NS_IMETHODIMP +nsSubscribableServer::GetImageSrc(int32_t aRow, nsTreeColumn* aCol, + nsAString& retval) { + return NS_OK; +} + +NS_IMETHODIMP +nsSubscribableServer::CycleHeader(nsTreeColumn* aCol) { return NS_OK; } + +NS_IMETHODIMP +nsSubscribableServer::SelectionChangedXPCOM() { return NS_OK; } + +NS_IMETHODIMP +nsSubscribableServer::CycleCell(int32_t aRow, nsTreeColumn* aCol) { + return NS_OK; +} -- cgit v1.2.3