transport: empty test for sqlite converter
[abstract.git] / view / aaTreeView.cpp
blobcdcad05aa5745020a791e0d425aa2da420474a7e
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:set ts=2 sw=2 sts=2 et cindent tw=79 ft=cpp: */
3 /*
4 * Copyright (C) 2007,2008 Sergey Yanovich <ynvich@gmail.com>
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of the
9 * License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public
17 * License along with this program; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
22 #include "xpcom-config.h"
24 #include "nsStringAPI.h"
25 #include "nsIDOMElement.h"
26 #include "nsIDOMNode.h"
27 #include "nsIDOMDocument.h"
28 #include "nsIDOMXULElement.h"
29 #include "nsIInterfaceRequestorUtils.h"
30 #include "nsISHistory.h"
31 #include "nsServiceManagerUtils.h"
32 #include "nsIObserverService.h"
33 #include "nsComponentManagerUtils.h"
35 /* Unfrozen API */
36 #include "nsITreeSelection.h"
37 #include "nsITreeColumns.h"
38 #include "nsITreeBoxObject.h"
39 #include "nsIArray.h"
40 #include "nsArrayUtils.h"
41 #include "nsClassHashtable.h"
43 /* Project includes */
44 #include "aaTreeView.h"
45 #include "aaISession.h"
46 #include "aaISqlTransaction.h"
47 #include "aaISqlRequest.h"
48 #include "aaBaseLoaders.h"
50 #include "aaIOrderCondition.h"
51 #include "aaIFilterCondition.h"
52 #include "aaConditionKeys.h"
53 #include "aaISqlFilter.h"
55 /*******************************************************************/
56 class CTreeViewFilters : public aaITreeViewFilters
58 public:
59 class CTreeViewFilter
61 public:
62 CTreeViewFilter(nsITreeColumn* col, const nsAString& param)
63 : mColumn(col)
64 , mParam(param)
67 ~CTreeViewFilter() {
69 public:
70 NS_IMETHOD GetColumn(nsITreeColumn** col) {
71 NS_ENSURE_ARG_POINTER(col);
72 NS_IF_ADDREF(*col = mColumn);
73 return NS_OK;
75 NS_IMETHOD GetParam(nsAString& param) {
76 param.Truncate();
77 param = mParam;
78 return NS_OK;
80 protected:
81 nsCOMPtr<nsITreeColumn> mColumn;
82 nsAutoString mParam;
84 public:
85 CTreeViewFilters();
86 NS_DECL_ISUPPORTS
87 NS_DECL_AAITREEVIEWFILTERS
88 protected:
89 ~CTreeViewFilters();
90 protected:
91 typedef nsClassHashtable<nsUint32HashKey, CTreeViewFilter> aaFilterHashtable;
92 aaFilterHashtable mContainer;
95 NS_IMPL_ISUPPORTS1(CTreeViewFilters, aaITreeViewFilters)
97 CTreeViewFilters::CTreeViewFilters() {
98 mContainer.Init();
101 CTreeViewFilters::~CTreeViewFilters() {
104 NS_IMETHODIMP
105 CTreeViewFilters::AddFilter(PRInt16 type, nsITreeColumn* col, const nsAString& param)
107 NS_ENSURE_ARG_POINTER(col);
108 if (!mContainer.Put(PRUint32(type), new CTreeViewFilter(col, param))) {
109 return NS_ERROR_FAILURE;
111 return NS_OK;
114 NS_IMETHODIMP
115 CTreeViewFilters::Clear()
117 mContainer.Clear();
118 return NS_OK;
121 PLDHashOperator EnumFunc(const PRUint32& type, nsAutoPtr<CTreeViewFilters::CTreeViewFilter>& filter, void* userArg)
123 if (nsnull != userArg) {
124 nsCOMPtr<nsITreeColumn> col;
125 nsAutoString param;
126 aaITreeFilterObserver* pObserver = (aaITreeFilterObserver*)userArg;
127 if (NS_SUCCEEDED(filter->GetColumn(getter_AddRefs(col))) && NS_SUCCEEDED(filter->GetParam(param))) {
128 PRBool moveNext = PR_TRUE;
129 if (NS_SUCCEEDED(pObserver->Next(PRInt16(type), col, param, &moveNext))) {
130 return moveNext ? PL_DHASH_NEXT : PL_DHASH_STOP;
134 return PL_DHASH_STOP;
137 NS_IMETHODIMP
138 CTreeViewFilters::Observe(aaITreeFilterObserver *observer)
140 NS_ENSURE_ARG_POINTER(observer);
141 mContainer.Enumerate((aaFilterHashtable::EnumFunction)&EnumFunc, observer);
142 return NS_OK;
145 NS_IMETHODIMP
146 CTreeViewFilters::IsExist(PRInt16 type, PRBool *_retval NS_OUTPARAM)
148 nsresult rc = NS_OK;
149 NS_ENSURE_ARG_POINTER(_retval);
150 *_retval = PR_FALSE;
151 CTreeViewFilter* pFilter = nsnull;
152 if (mContainer.Get(type, &pFilter)) {
153 *_retval = PR_TRUE;
155 return rc;
158 NS_IMETHODIMP
159 CTreeViewFilters::GetFilter(PRInt16 type, nsITreeColumn **col NS_OUTPARAM, nsAString & param NS_OUTPARAM)
161 nsresult rc = NS_OK;
162 CTreeViewFilter* pFilter = nsnull;
163 NS_ENSURE_ARG_POINTER(col);
164 if (!mContainer.Get(type, &pFilter)) {
165 return NS_ERROR_INVALID_ARG;
167 param.Truncate();
168 NS_ENSURE_SUCCESS(rc = pFilter->GetColumn(col), rc);
169 NS_ENSURE_SUCCESS(rc = pFilter->GetParam(param), rc);
170 return rc;
172 /*******************************************************************/
174 aaTreeView::aaTreeView()
175 : mFlags(0)
176 , mOldRowCount(0)
177 , mFilters(nsnull)
181 aaTreeView::~aaTreeView()
185 nsresult
186 aaTreeView::Init(nsISupports *aParam)
188 nsresult rv;
189 mSession = do_QueryInterface(aParam, &rv);
190 NS_ENSURE_SUCCESS(rv, rv);
192 return NS_OK;
195 NS_IMPL_ISUPPORTS3(aaTreeView,
196 aaIDataTreeView,
197 nsITreeView,
198 aaITreeFilterObserver)
200 NS_IMETHODIMP
201 aaTreeView::GetRowCount(PRInt32 *aRowCount)
203 NS_ENSURE_ARG_POINTER(aRowCount);
204 *aRowCount = 0;
205 if (! mDataSet)
206 return NS_OK;
208 return mDataSet->GetLength((PRUint32 *) aRowCount);
211 NS_IMETHODIMP
212 aaTreeView::GetSelection(nsITreeSelection * *aSelection)
214 NS_ENSURE_ARG_POINTER( aSelection );
215 NS_IF_ADDREF(*aSelection = mSelection);
216 return NS_OK;
218 NS_IMETHODIMP
219 aaTreeView::SetSelection(nsITreeSelection * aSelection)
221 mSelection = aSelection;
223 return NS_OK;
226 NS_IMETHODIMP
227 aaTreeView::GetRowProperties(PRInt32 index, nsISupportsArray *properties)
229 return NS_ERROR_NOT_IMPLEMENTED;
232 NS_IMETHODIMP
233 aaTreeView::GetCellProperties(PRInt32 row, nsITreeColumn *col, nsISupportsArray *properties)
235 return NS_ERROR_NOT_IMPLEMENTED;
238 NS_IMETHODIMP
239 aaTreeView::GetColumnProperties(nsITreeColumn *col, nsISupportsArray *properties)
241 return NS_ERROR_NOT_IMPLEMENTED;
244 NS_IMETHODIMP
245 aaTreeView::IsContainer(PRInt32 index, PRBool *_retval)
247 NS_ENSURE_ARG_POINTER(_retval);
248 *_retval = PR_FALSE;
249 return NS_OK;
252 NS_IMETHODIMP
253 aaTreeView::IsContainerOpen(PRInt32 index, PRBool *_retval)
255 return NS_ERROR_NOT_IMPLEMENTED;
258 NS_IMETHODIMP
259 aaTreeView::IsContainerEmpty(PRInt32 index, PRBool *_retval)
261 return NS_ERROR_NOT_IMPLEMENTED;
264 NS_IMETHODIMP
265 aaTreeView::IsSeparator(PRInt32 index, PRBool *_retval)
267 NS_ENSURE_ARG_POINTER(_retval);
268 *_retval = PR_FALSE;
269 return NS_OK;
272 NS_IMETHODIMP
273 aaTreeView::IsSorted(PRBool *_retval)
275 return NS_ERROR_NOT_IMPLEMENTED;
278 NS_IMETHODIMP
279 aaTreeView::CanDrop(PRInt32 index, PRInt32 orientation,
280 nsIDOMDataTransfer *dataTransfer, PRBool *_retval NS_OUTPARAM)
282 return NS_ERROR_NOT_IMPLEMENTED;
285 NS_IMETHODIMP
286 aaTreeView::Drop(PRInt32 row, PRInt32 orientation,
287 nsIDOMDataTransfer *dataTransfer)
289 return NS_ERROR_NOT_IMPLEMENTED;
292 NS_IMETHODIMP
293 aaTreeView::GetParentIndex(PRInt32 rowIndex, PRInt32 *_retval)
295 return NS_ERROR_NOT_IMPLEMENTED;
298 NS_IMETHODIMP
299 aaTreeView::HasNextSibling(PRInt32 rowIndex, PRInt32 afterIndex, PRBool *_retval)
301 NS_ENSURE_ARG_POINTER(_retval);
302 nsresult rv;
303 PRInt32 count;
304 rv = GetRowCount(&count);
305 NS_ENSURE_SUCCESS(rv, rv);
306 if (rowIndex == afterIndex && rowIndex < count) {
307 *_retval = PR_TRUE;
308 } else {
309 *_retval = PR_FALSE;
311 return NS_OK;
314 NS_IMETHODIMP
315 aaTreeView::GetLevel(PRInt32 index, PRInt32 *_retval)
317 NS_ENSURE_ARG_POINTER(_retval);
318 *_retval = 0;
319 return NS_OK;
322 NS_IMETHODIMP
323 aaTreeView::GetImageSrc(PRInt32 row, nsITreeColumn *col, nsAString & _retval)
325 return NS_ERROR_NOT_IMPLEMENTED;
328 NS_IMETHODIMP
329 aaTreeView::GetProgressMode(PRInt32 row, nsITreeColumn *col, PRInt32 *_retval)
331 return NS_ERROR_NOT_IMPLEMENTED;
334 NS_IMETHODIMP
335 aaTreeView::GetCellValue(PRInt32 row, nsITreeColumn *col, nsAString & _retval)
337 return NS_ERROR_NOT_IMPLEMENTED;
340 NS_IMETHODIMP
341 aaTreeView::GetCellText(PRInt32 row, nsITreeColumn *col, nsAString & _retval)
343 /**
344 * There may be a bug in <tree> implementation. This function is
345 * occasionally called after mTree is detached by SetTree(nsnull);
347 NS_ENSURE_TRUE(mDataSet, NS_ERROR_NOT_INITIALIZED);
348 NS_ENSURE_TRUE(row >= 0, NS_ERROR_INVALID_ARG);
349 return doGetCellText(row, col, _retval);
352 NS_IMETHODIMP
353 aaTreeView::SetTree(nsITreeBoxObject *tree)
355 mTree = tree;
356 return NS_OK;
359 NS_IMETHODIMP
360 aaTreeView::ToggleOpenState(PRInt32 index)
362 return NS_ERROR_NOT_IMPLEMENTED;
365 NS_IMETHODIMP
366 aaTreeView::CycleHeader(nsITreeColumn *col)
368 //when column clicked, method was called by treecol handler
369 return NS_OK;//NS_ERROR_NOT_IMPLEMENTED;
372 NS_IMETHODIMP
373 aaTreeView::SelectionChanged()
375 return NS_OK;
378 NS_IMETHODIMP
379 aaTreeView::CycleCell(PRInt32 row, nsITreeColumn *col)
381 return NS_ERROR_NOT_IMPLEMENTED;
384 NS_IMETHODIMP
385 aaTreeView::IsEditable(PRInt32 row, nsITreeColumn *col, PRBool *_retval)
387 return NS_ERROR_NOT_IMPLEMENTED;
390 NS_IMETHODIMP
391 aaTreeView::IsSelectable(PRInt32 row, nsITreeColumn *col, PRBool *_retval)
393 NS_ENSURE_ARG_POINTER(_retval);
394 *_retval = PR_TRUE;
395 return NS_OK;
398 NS_IMETHODIMP
399 aaTreeView::SetCellValue(PRInt32 row, nsITreeColumn *col, const nsAString & value)
401 return NS_ERROR_NOT_IMPLEMENTED;
404 NS_IMETHODIMP
405 aaTreeView::SetCellText(PRInt32 row, nsITreeColumn *col, const nsAString & value)
407 return NS_ERROR_NOT_IMPLEMENTED;
410 NS_IMETHODIMP
411 aaTreeView::PerformAction(const PRUnichar *action)
413 return NS_ERROR_NOT_IMPLEMENTED;
416 NS_IMETHODIMP
417 aaTreeView::PerformActionOnRow(const PRUnichar *action, PRInt32 row)
419 return NS_ERROR_NOT_IMPLEMENTED;
422 NS_IMETHODIMP
423 aaTreeView::PerformActionOnCell(const PRUnichar *action, PRInt32 row, nsITreeColumn *col)
425 return NS_ERROR_NOT_IMPLEMENTED;
428 /* aaIDataTreeView */
429 NS_IMETHODIMP
430 aaTreeView::GetDataSet(nsIArray * * aDataSet)
432 NS_ENSURE_ARG_POINTER(aDataSet);
433 NS_IF_ADDREF(*aDataSet = mDataSet);
434 return NS_OK;
437 NS_IMETHODIMP aaTreeView::GetOldRowCount(PRInt32* aRowCount) {
438 *aRowCount = mOldRowCount;
439 return NS_OK;
442 NS_IMETHODIMP aaTreeView::RowCountChanged(PRInt32 aOldRowCount, PRInt32 aNewRowCount) {
443 if (mOldRowCount == aOldRowCount) {
444 mOldRowCount = aNewRowCount;
445 return NS_OK;
447 return NS_ERROR_INVALID_ARG;
450 NS_IMETHODIMP
451 aaTreeView::Update(nsISupports *aParam = 0)
453 NS_ENSURE_TRUE(mDataLoader || mComplexLoader, NS_ERROR_NOT_INITIALIZED);
454 nsresult rv;
455 PRInt32 oldCount = 0;
456 PRInt32 newRowCount = 0;
459 rv = GetOldRowCount(&oldCount);
460 NS_ENSURE_SUCCESS(rv, rv);
462 if (mTree) {
463 mTree->RowCountChanged(0, - oldCount);
466 rv = buildFilter(aParam);
467 NS_ENSURE_SUCCESS(rv, rv);
469 if (mDataLoader) {
470 rv = mDataLoader->SetFilter(mFilter);
471 NS_ENSURE_SUCCESS(rv, rv);
473 rv = mSession->Load(mDataLoader, getter_AddRefs(mDataSet));
474 NS_ENSURE_SUCCESS(rv, rv);
476 rv = postLoadHandler();
477 NS_ENSURE_SUCCESS(rv, rv);
479 else {
480 nsCOMPtr<nsISupports> supReturn;
482 rv = mComplexLoader->SetParam(mFilter);
483 NS_ENSURE_SUCCESS(rv, rv);
485 rv = mSession->Execute(mComplexLoader, getter_AddRefs(supReturn));
486 NS_ENSURE_SUCCESS(rv, rv);
487 NS_ENSURE_TRUE(supReturn, NS_ERROR_UNEXPECTED);
489 rv = supReturn->QueryInterface(NS_GET_IID(nsIArray), getter_AddRefs(mDataSet));
490 NS_ENSURE_SUCCESS(rv, rv);
493 rv = GetRowCount(&newRowCount);
494 NS_ENSURE_SUCCESS(rv, rv);
496 rv = RowCountChanged(oldCount, newRowCount);
497 NS_ENSURE_SUCCESS(rv, rv);
499 if (mTree) {
500 mTree->RowCountChanged(0, newRowCount);
503 nsCOMPtr<nsIObserverService> broadcaster = do_GetService("@mozilla.org/observer-service;1");
504 NS_ENSURE_TRUE(broadcaster, NS_OK);
505 broadcaster->NotifyObservers(reinterpret_cast<nsISupports*>(this), "tree-view-load", nsnull);
507 rv = dataLoadSuccess();
508 NS_ENSURE_SUCCESS(rv, rv);
510 return NS_OK;
513 NS_IMETHODIMP
514 aaTreeView::GetFlags(PRUint32 *aFlags)
516 NS_ENSURE_ARG_POINTER(aFlags);
517 *aFlags = mFlags;
518 return NS_OK;
520 NS_IMETHODIMP
521 aaTreeView::SetFlags(PRUint32 aFlags)
523 PRBool needUpdate = (aFlags != mFlags);
524 mFlags = aFlags;
525 if (NS_LIKELY( needUpdate && mTree )) {
526 mTree->Invalidate();
527 nsCOMPtr<nsIObserverService> broadcaster = do_GetService(
528 "@mozilla.org/observer-service;1");
529 NS_ENSURE_TRUE(broadcaster, NS_OK);
530 broadcaster->NotifyObservers(reinterpret_cast<nsISupports*>(this), "tree-flags-change", nsnull);
532 return NS_OK;
535 /* Protected methods */
536 nsresult
537 aaTreeView::postLoadHandler()
539 return NS_OK;
542 PRInt32
543 aaTreeView::getColumnIndex(nsITreeColumn *col, PRUint32 colPtrSz)
545 nsresult rv;
546 NS_ENSURE_TRUE(col, -1);
548 PRInt32 ci;
549 rv = col->GetIndex(&ci);
550 NS_ENSURE_SUCCESS(rv, -1);
552 NS_ENSURE_TRUE(ci >= 0 && ci < (PRInt32) (colPtrSz / sizeof(int *)), -1);
554 return ci;
557 NS_IMETHODIMP
558 aaTreeView::GetFilters(aaITreeViewFilters **aFilters)
560 NS_ENSURE_ARG_POINTER(aFilters);
561 if (!mFilters) {
562 //mFilters
563 (new CTreeViewFilters)->QueryInterface(NS_GET_IID(aaITreeViewFilters), getter_AddRefs(mFilters));
564 NS_ENSURE_TRUE(mFilters, NS_ERROR_NULL_POINTER);
566 if (NS_IF_ADDREF(mFilters)) {
567 *aFilters = mFilters;
568 } else {
569 *aFilters = nsnull;
570 return NS_ERROR_FAILURE;
572 return NS_OK;
575 NS_IMETHODIMP
576 aaTreeView::Next(PRInt16 type, nsITreeColumn *col, const nsAString & param, PRBool *_retval)
578 nsresult rc = NS_OK;
579 NS_ENSURE_ARG_POINTER(col);
580 NS_ENSURE_ARG_POINTER(_retval);
581 NS_ENSURE_TRUE(mFilter, NS_ERROR_NOT_INITIALIZED);
582 *_retval = PR_FALSE;
583 if (PRInt16(aaITreeViewFilters::FILTER_SORT) == type) {
584 nsCOMPtr<aaIOrderCondition> order;
585 nsCAutoString name;
586 //do create order condition
587 rc = createOrderCondition(col, param, getter_AddRefs(order));
588 NS_ENSURE_SUCCESS(rc, rc);
589 //do get condition name
590 rc = order->GetConditionName(name);
591 NS_ENSURE_SUCCESS(rc, rc);
592 //do add order to filter
593 rc = mFilter->AddParam(name, order);
594 NS_ENSURE_SUCCESS(rc, rc);
595 } else if(PRInt16(aaITreeViewFilters::FILTER_FILTER) == type) {
596 nsCOMPtr<aaIFilterCondition> filter;
597 nsCAutoString name;
598 //do create order condition
599 rc = createFilterCondition(col, param, getter_AddRefs(filter));
600 NS_ENSURE_SUCCESS(rc, rc);
601 //do get condition name
602 rc = filter->GetConditionName(name);
603 NS_ENSURE_SUCCESS(rc, rc);
604 //do add order to filter
605 rc = mFilter->AddParam(name, filter);
606 NS_ENSURE_SUCCESS(rc, rc);
607 } else {
608 return NS_ERROR_INVALID_ARG;
610 *_retval = PR_TRUE;
611 return rc;
614 NS_IMETHODIMP
615 aaTreeView::buildFilter(nsISupports* aParam)
617 nsresult rc = NS_OK;
618 if (mFilter) {
619 mFilter = nsnull;
622 if (mFilters || aParam) {
623 mFilter = do_CreateInstance(AA_SQLFILTER_CONTRACT, &rc);
624 NS_ENSURE_SUCCESS(rc, rc);
627 if (mFilters) {
628 nsCOMPtr<aaITreeFilterObserver> pObserver;
629 this->QueryInterface(NS_GET_IID(aaITreeFilterObserver), getter_AddRefs(pObserver));
630 NS_ENSURE_SUCCESS(rc, rc);
631 //do observe params
632 rc = mFilters->Observe(pObserver);
633 NS_ENSURE_SUCCESS(rc, rc);
636 if (aParam) {
637 //add param to filter
638 rc = mFilter->SetInterface(aParam->GetIID(), aParam);
639 NS_ENSURE_SUCCESS(rc, rc);
641 return rc;
644 nsresult
645 aaTreeView::createOrderCondition(nsITreeColumn* col, const nsAString& param, aaIOrderCondition** _retval)
647 nsresult rc = NS_OK;
648 nsCAutoString column;
649 nsCOMPtr<aaIOrderCondition> order;
651 NS_ENSURE_ARG_POINTER(col);
652 NS_ENSURE_ARG_POINTER(_retval);
653 NS_ENSURE_ARG_POINTER(!param.IsEmpty());
655 order = do_CreateInstance(AA_ORDER_CONDITION_CONTRACTID, &rc);
656 NS_ENSURE_SUCCESS(rc, rc);
658 rc = convertSortColumnToString(col, column);
659 NS_ENSURE_SUCCESS(rc, rc);
661 rc = order->AddOrder(column, (param.Compare(NS_LITERAL_STRING("ascending")) == 0 ? PRInt16(aaIOrderCondition::SORT_ASC) : PRInt16(aaIOrderCondition::SORT_DESC)));
662 NS_ENSURE_SUCCESS(rc, rc);
664 if (NS_IF_ADDREF(order)) {
665 *_retval = order;
666 } else {
667 *_retval = nsnull;
668 return NS_ERROR_UNEXPECTED;
670 return rc;
673 nsresult
674 aaTreeView::createFilterCondition(nsITreeColumn* col, const nsAString& param, aaIFilterCondition** _retval)
676 nsresult rc = NS_OK;
677 nsCAutoString column;
678 nsCOMPtr<aaIFilterCondition> filter;
680 NS_ENSURE_ARG_POINTER(col);
681 NS_ENSURE_ARG_POINTER(_retval);
682 NS_ENSURE_ARG_POINTER(!param.IsEmpty());
684 filter = do_CreateInstance(AA_FILTER_CONDITION_CONTRACTID, &rc);
685 NS_ENSURE_SUCCESS(rc, rc);
687 rc = convertSortColumnToString(col, column);
688 NS_ENSURE_SUCCESS(rc, rc);
690 rc = filter->AddFilter(column, NS_ConvertUTF16toUTF8(param));
691 NS_ENSURE_SUCCESS(rc, rc);
693 if (NS_IF_ADDREF(filter)) {
694 *_retval = filter;
695 } else {
696 *_retval = nsnull;
697 return NS_ERROR_UNEXPECTED;
699 return rc;
702 NS_IMETHODIMP
703 aaTreeView::dataLoadSuccess()
705 return NS_OK;