update ooo310-m15
[ooovba.git] / applied_patches / 0527-calc-dp-custom-sort.diff
blob85173af52c0875f8d1b54f1acbcafcc215683a36
1 diff --git sc/inc/sc.hrc sc/inc/sc.hrc
2 index 3ecd9ba..32f883a 100644
3 --- sc/inc/sc.hrc
4 +++ sc/inc/sc.hrc
5 @@ -1682,6 +1682,9 @@
6 // Language chooser for text import filters.
7 #define RID_SCDLG_LANG_CHOOSER (SC_OOO_BUILD_START + 12)
9 +// Datapilot controls
10 +#define RID_SC_DPCONTROL (SC_OOO_BUILD_START + 13)
12 #endif
15 diff --git sc/source/ui/cctrl/dpcontrol.cxx sc/source/ui/cctrl/dpcontrol.cxx
16 index e188ab3..02fb0b9 100644
17 --- sc/source/ui/cctrl/dpcontrol.cxx
18 +++ sc/source/ui/cctrl/dpcontrol.cxx
19 @@ -38,6 +38,9 @@
20 #include "vcl/outdev.hxx"
21 #include "vcl/settings.hxx"
22 #include "vcl/wintypes.hxx"
23 +#include "vcl/decoview.hxx"
25 +#define MENU_NOT_SELECTED 999
27 using ::rtl::OUString;
28 using ::rtl::OUStringHash;
29 @@ -182,6 +185,525 @@ void ScDPFieldButton::drawPopupButton()
31 // ============================================================================
33 +ScMenuFloatingWindow::MenuItem::MenuItem() :
34 + mbEnabled(true),
35 + mpAction(static_cast<ScDPFieldPopupWindow::Action*>(NULL)),
36 + mpSubMenuWin(static_cast<ScMenuFloatingWindow*>(NULL))
40 +// ----------------------------------------------------------------------------
42 +ScMenuFloatingWindow::SubMenuItem::SubMenuItem(ScMenuFloatingWindow* pParent) :
43 + mpSubMenu(NULL),
44 + mnMenuPos(MENU_NOT_SELECTED),
45 + mpParent(pParent)
47 + maTimer.SetTimeoutHdl( LINK(this, ScMenuFloatingWindow::SubMenuItem, TimeoutHdl) );
48 + maTimer.SetTimeout(mpParent->GetSettings().GetMouseSettings().GetMenuDelay());
51 +void ScMenuFloatingWindow::SubMenuItem::reset()
53 + mpSubMenu = NULL;
54 + mnMenuPos = MENU_NOT_SELECTED;
55 + maTimer.Stop();
58 +IMPL_LINK( ScMenuFloatingWindow::SubMenuItem, TimeoutHdl, void*, EMPTYARG )
60 + mpParent->handleMenuTimeout(this);
61 + return 0;
64 +// ----------------------------------------------------------------------------
66 +ScMenuFloatingWindow::ScMenuFloatingWindow(Window* pParent) :
67 + FloatingWindow(pParent, (WB_SYSTEMFLOATWIN|WB_SYSTEMWINDOW|WB_NOBORDER)),
68 + maOpenTimer(this),
69 + maCloseTimer(this),
70 + mnSelectedMenu(MENU_NOT_SELECTED),
71 + mnClickedMenu(MENU_NOT_SELECTED),
72 + mpParentMenu(dynamic_cast<ScMenuFloatingWindow*>(pParent)),
73 + mpActiveSubMenu(NULL),
74 + mbActionFired(false)
76 + // TODO: How do we get the right font to use here ?
77 + const sal_uInt16 nPopupFontHeight = 12;
78 + const StyleSettings& rStyle = GetSettings().GetStyleSettings();
79 + maLabelFont = rStyle.GetLabelFont();
80 + maLabelFont.SetHeight(nPopupFontHeight);
81 + SetFont(maLabelFont);
83 + SetPopupModeEndHdl( LINK(this, ScMenuFloatingWindow, EndPopupHdl) );
86 +ScMenuFloatingWindow::~ScMenuFloatingWindow()
88 + EndPopupMode();
91 +void ScMenuFloatingWindow::MouseMove(const MouseEvent& rMEvt)
93 + const Point& rPos = rMEvt.GetPosPixel();
94 + size_t nSelectedMenu = getEnclosingMenuItem(rPos);
95 + setSelectedMenuItem(nSelectedMenu);
97 + Window::MouseMove(rMEvt);
100 +void ScMenuFloatingWindow::MouseButtonDown(const MouseEvent& rMEvt)
102 + const Point& rPos = rMEvt.GetPosPixel();
103 + mnClickedMenu = getEnclosingMenuItem(rPos);
104 + Window::MouseButtonDown(rMEvt);
107 +void ScMenuFloatingWindow::MouseButtonUp(const MouseEvent& rMEvt)
109 + executeMenu(mnClickedMenu);
110 + mnClickedMenu = MENU_NOT_SELECTED;
111 + Window::MouseButtonUp(rMEvt);
114 +void ScMenuFloatingWindow::KeyInput(const KeyEvent& rKEvt)
116 + const KeyCode& rKeyCode = rKEvt.GetKeyCode();
117 + bool bHandled = true;
118 + size_t nSelectedMenu = mnSelectedMenu;
119 + size_t nLastMenuPos = maMenuItems.size() - 1;
120 + switch (rKeyCode.GetCode())
122 + case KEY_UP:
123 + if (nSelectedMenu == MENU_NOT_SELECTED || nSelectedMenu == 0)
124 + nSelectedMenu = nLastMenuPos;
125 + else
126 + --nSelectedMenu;
127 + setSelectedMenuItem(nSelectedMenu, false);
128 + break;
129 + case KEY_DOWN:
130 + if (nSelectedMenu == MENU_NOT_SELECTED || nSelectedMenu == nLastMenuPos)
131 + nSelectedMenu = 0;
132 + else
133 + ++nSelectedMenu;
134 + setSelectedMenuItem(nSelectedMenu, false);
135 + break;
136 + case KEY_LEFT:
137 + if (mpParentMenu)
138 + mpParentMenu->endSubMenu();
139 + break;
140 + case KEY_RIGHT:
142 + if (mnSelectedMenu >= maMenuItems.size() || mnSelectedMenu == MENU_NOT_SELECTED)
143 + break;
145 + const MenuItem& rMenu = maMenuItems[mnSelectedMenu];
146 + if (!rMenu.mbEnabled || !rMenu.mpSubMenuWin)
147 + break;
149 + maOpenTimer.mnMenuPos = mnSelectedMenu;
150 + maOpenTimer.mpSubMenu = rMenu.mpSubMenuWin.get();
151 + launchSubMenu(true);
153 + break;
154 + case KEY_RETURN:
155 + if (nSelectedMenu != MENU_NOT_SELECTED)
156 + executeMenu(nSelectedMenu);
157 + break;
158 + default:
159 + bHandled = false;
162 + if (!bHandled)
163 + Window::KeyInput(rKEvt);
166 +void ScMenuFloatingWindow::Paint(const Rectangle& /*rRect*/)
168 + const StyleSettings& rStyle = GetSettings().GetStyleSettings();
169 + Color aBackColor = rStyle.GetMenuColor();
170 + Color aBorderColor = rStyle.GetShadowColor();
172 + Rectangle aCtrlRect(Point(0, 0), GetOutputSizePixel());
174 + // Window background
175 + bool bNativeDrawn = true;
176 + if (IsNativeControlSupported(CTRL_MENU_POPUP, PART_ENTIRE_CONTROL))
178 + SetClipRegion();
179 + bNativeDrawn = DrawNativeControl(
180 + CTRL_MENU_POPUP, PART_ENTIRE_CONTROL, Region(aCtrlRect), CTRL_STATE_ENABLED,
181 + ImplControlValue(), OUString());
183 + else
184 + bNativeDrawn = false;
186 + if (!bNativeDrawn)
188 + SetFillColor(aBackColor);
189 + SetLineColor(aBorderColor);
190 + DrawRect(aCtrlRect);
193 + // Menu items
194 + SetTextColor(rStyle.GetMenuTextColor());
195 + drawAllMenuItems();
198 +void ScMenuFloatingWindow::addMenuItem(const OUString& rText, bool bEnabled, Action* pAction)
200 + MenuItem aItem;
201 + aItem.maText = rText;
202 + aItem.mbEnabled = bEnabled;
203 + aItem.mpAction.reset(pAction);
204 + maMenuItems.push_back(aItem);
207 +ScMenuFloatingWindow* ScMenuFloatingWindow::addSubMenuItem(const OUString& rText, bool bEnabled)
209 + MenuItem aItem;
210 + aItem.maText = rText;
211 + aItem.mbEnabled = bEnabled;
212 + aItem.mpSubMenuWin.reset(new ScMenuFloatingWindow(this));
213 + maMenuItems.push_back(aItem);
214 + return aItem.mpSubMenuWin.get();
217 +void ScMenuFloatingWindow::drawMenuItem(size_t nPos)
219 + if (nPos >= maMenuItems.size())
220 + return;
222 + Point aPos;
223 + Size aSize;
224 + getMenuItemPosSize(aPos, aSize, nPos);
226 + DecorationView aDecoView(this);
227 + long nXOffset = 5;
228 + long nYOffset = (aSize.Height() - maLabelFont.GetHeight())/2;
229 + DrawCtrlText(Point(aPos.X()+nXOffset, aPos.Y() + nYOffset), maMenuItems[nPos].maText, 0, STRING_LEN,
230 + maMenuItems[nPos].mbEnabled ? TEXT_DRAW_MNEMONIC : TEXT_DRAW_DISABLE);
232 + if (maMenuItems[nPos].mpSubMenuWin)
234 + long nFontHeight = maLabelFont.GetHeight();
235 + Point aMarkerPos = aPos;
236 + aMarkerPos.Y() += aSize.Height()/2 - nFontHeight/4 + 1;
237 + aMarkerPos.X() += aSize.Width() - nFontHeight + nFontHeight/4;
238 + Size aMarkerSize(nFontHeight/2, nFontHeight/2);
239 + aDecoView.DrawSymbol(Rectangle(aMarkerPos, aMarkerSize),
240 + SYMBOL_SPIN_RIGHT, GetTextColor(), 0);
244 +void ScMenuFloatingWindow::drawAllMenuItems()
246 + size_t n = maMenuItems.size();
247 + for (size_t i = 0; i < n; ++i)
248 + highlightMenuItem(i, i == mnSelectedMenu);
251 +const Font& ScMenuFloatingWindow::getLabelFont() const
253 + return maLabelFont;
256 +void ScMenuFloatingWindow::executeMenu(size_t nPos)
258 + if (nPos >= maMenuItems.size())
259 + return;
261 + if (!maMenuItems[nPos].mpAction)
262 + // no action is defined.
263 + return;
265 + maMenuItems[nPos].mpAction->execute();
266 + mbActionFired = true;
267 + EndPopupMode();
270 +void ScMenuFloatingWindow::setSelectedMenuItem(size_t nPos, bool bSubMenuTimer)
272 + if (mnSelectedMenu != nPos)
274 + selectMenuItem(mnSelectedMenu, false, bSubMenuTimer);
275 + selectMenuItem(nPos, true, bSubMenuTimer);
276 + mnSelectedMenu = nPos;
280 +size_t ScMenuFloatingWindow::getSelectedMenuItem() const
282 + return mnSelectedMenu;
285 +void ScMenuFloatingWindow::handleMenuTimeout(SubMenuItem* pTimer)
287 + if (pTimer == &maOpenTimer)
289 + // Close any open submenu immediately.
290 + if (maCloseTimer.mpSubMenu)
292 + maCloseTimer.mpSubMenu->EndPopupMode();
293 + maCloseTimer.mpSubMenu = NULL;
294 + maCloseTimer.maTimer.Stop();
297 + launchSubMenu(false);
299 + else if (pTimer == &maCloseTimer)
301 + // end submenu.
302 + if (maCloseTimer.mpSubMenu)
304 + maOpenTimer.mpSubMenu = NULL;
306 + maCloseTimer.mpSubMenu->EndPopupMode();
307 + maCloseTimer.mpSubMenu = NULL;
309 + highlightMenuItem(maOpenTimer.mnMenuPos, false);
310 + maOpenTimer.mnMenuPos = MENU_NOT_SELECTED;
315 +void ScMenuFloatingWindow::queueLaunchSubMenu(size_t nPos, ScMenuFloatingWindow* pMenu)
317 + if (!pMenu)
318 + return;
320 + // Set the submenu on launch queue.
321 + if (maOpenTimer.mpSubMenu)
323 + if (maOpenTimer.mpSubMenu == pMenu)
325 + if (pMenu == maCloseTimer.mpSubMenu)
326 + maCloseTimer.reset();
327 + return;
330 + // new submenu is being requested.
331 + queueCloseSubMenu();
334 + maOpenTimer.mpSubMenu = pMenu;
335 + maOpenTimer.mnMenuPos = nPos;
336 + maOpenTimer.maTimer.Start();
339 +void ScMenuFloatingWindow::queueCloseSubMenu()
341 + if (!maOpenTimer.mpSubMenu)
342 + // There is no submenu to close.
343 + return;
345 + // Stop any submenu on queue for opening.
346 + maOpenTimer.maTimer.Stop();
348 + maCloseTimer.mpSubMenu = maOpenTimer.mpSubMenu;
349 + maCloseTimer.mnMenuPos = maOpenTimer.mnMenuPos;
350 + maCloseTimer.maTimer.Start();
353 +void ScMenuFloatingWindow::launchSubMenu(bool bSetMenuPos)
355 + Point aPos;
356 + Size aSize;
357 + getMenuItemPosSize(aPos, aSize, maOpenTimer.mnMenuPos);
358 + ScMenuFloatingWindow* pSubMenu = maOpenTimer.mpSubMenu;
360 + if (!pSubMenu)
361 + return;
363 + sal_uInt32 nOldFlags = GetPopupModeFlags();
364 + SetPopupModeFlags(nOldFlags | FLOATWIN_POPUPMODE_NOAPPFOCUSCLOSE);
365 + pSubMenu->resetMenu(bSetMenuPos);
366 + pSubMenu->StartPopupMode(
367 + Rectangle(aPos,aSize), (FLOATWIN_POPUPMODE_RIGHT | FLOATWIN_POPUPMODE_GRABFOCUS));
368 + pSubMenu->AddPopupModeWindow(this);
369 + SetPopupModeFlags(nOldFlags);
372 +void ScMenuFloatingWindow::endSubMenu()
374 + if (maOpenTimer.mpSubMenu)
376 + maOpenTimer.mpSubMenu->EndPopupMode();
377 + maOpenTimer.mpSubMenu = NULL;
378 + highlightMenuItem(maOpenTimer.mnMenuPos, true);
382 +void ScMenuFloatingWindow::notify(NotificationType eType)
384 + switch (eType)
386 + case SUBMENU_FOCUSED:
387 + // Cancel any request for ending submenu.
388 + maCloseTimer.reset();
389 + if (mnSelectedMenu != maOpenTimer.mnMenuPos)
391 + highlightMenuItem(maOpenTimer.mnMenuPos, true);
392 + mnSelectedMenu = maOpenTimer.mnMenuPos;
394 + break;
395 + default:
400 +void ScMenuFloatingWindow::resetMenu(bool bSetMenuPos)
402 + mnSelectedMenu = bSetMenuPos ? 0 : MENU_NOT_SELECTED;
403 + resizeToFitMenuItems();
406 +void ScMenuFloatingWindow::resizeToFitMenuItems()
408 + if (maMenuItems.empty())
409 + return;
411 + vector<MenuItem>::const_iterator itr = maMenuItems.begin(), itrEnd = maMenuItems.end();
412 + long nTextWidth = 0;
413 + for (; itr != itrEnd; ++itr)
414 + nTextWidth = ::std::max(GetTextWidth(itr->maText), nTextWidth);
416 + size_t nLastPos = maMenuItems.size()-1;
417 + Point aPos;
418 + Size aSize;
419 + getMenuItemPosSize(aPos, aSize, nLastPos);
420 + aPos.X() += nTextWidth + 15;
421 + aPos.Y() += aSize.Height() + 5;
422 + SetOutputSizePixel(Size(aPos.X(), aPos.Y()));
425 +void ScMenuFloatingWindow::selectMenuItem(size_t nPos, bool bSelected, bool bSubMenuTimer)
427 + if (nPos >= maMenuItems.size() || nPos == MENU_NOT_SELECTED)
429 + queueCloseSubMenu();
430 + return;
433 + if (!maMenuItems[nPos].mbEnabled)
434 + {
435 + queueCloseSubMenu();
436 + return;
439 + highlightMenuItem(nPos, bSelected);
441 + if (bSelected)
443 + if (mpParentMenu)
444 + mpParentMenu->notify(SUBMENU_FOCUSED);
446 + if (bSubMenuTimer)
448 + if (maMenuItems[nPos].mpSubMenuWin)
450 + ScMenuFloatingWindow* pSubMenu = maMenuItems[nPos].mpSubMenuWin.get();
451 + queueLaunchSubMenu(nPos, pSubMenu);
453 + else
454 + queueCloseSubMenu();
459 +void ScMenuFloatingWindow::highlightMenuItem(size_t nPos, bool bSelected)
461 + const StyleSettings& rStyle = GetSettings().GetStyleSettings();
462 + Color aBackColor = rStyle.GetMenuColor();
463 + SetFillColor(aBackColor);
464 + SetLineColor(aBackColor);
466 + Point aPos;
467 + Size aSize;
468 + getMenuItemPosSize(aPos, aSize, nPos);
469 + Region aRegion(Rectangle(aPos,aSize));
471 + if (IsNativeControlSupported(CTRL_MENU_POPUP, PART_ENTIRE_CONTROL))
473 + Push(PUSH_CLIPREGION);
474 + IntersectClipRegion(Rectangle(aPos, aSize));
475 + Rectangle aCtrlRect(Point(0,0), GetOutputSizePixel());
476 + DrawNativeControl(
477 + CTRL_MENU_POPUP, PART_ENTIRE_CONTROL, Region(aCtrlRect), CTRL_STATE_ENABLED,
478 + ImplControlValue(), OUString());
480 + Pop();
483 + bool bNativeDrawn = true;
484 + if (IsNativeControlSupported(CTRL_MENU_POPUP, PART_MENU_ITEM))
486 + ControlState nState = bSelected ? CTRL_STATE_SELECTED : 0;
487 + if (maMenuItems[nPos].mbEnabled)
488 + nState |= CTRL_STATE_ENABLED;
489 + bNativeDrawn = DrawNativeControl(
490 + CTRL_MENU_POPUP, PART_MENU_ITEM, aRegion, nState, ImplControlValue(), OUString());
492 + else
493 + bNativeDrawn = false;
495 + if (!bNativeDrawn)
497 + if (bSelected)
499 + aBackColor = rStyle.GetMenuHighlightColor();
500 + SetFillColor(aBackColor);
501 + SetLineColor(aBackColor);
503 + DrawRect(Rectangle(aPos,aSize));
506 + Color aTextColor = bSelected ? rStyle.GetMenuHighlightTextColor() : rStyle.GetMenuTextColor();
507 + SetTextColor(aTextColor);
508 + drawMenuItem(nPos);
511 +void ScMenuFloatingWindow::getMenuItemPosSize(Point& rPos, Size& rSize, size_t nPos) const
513 + const sal_uInt16 nLeftMargin = 5;
514 + const sal_uInt16 nTopMargin = 5;
515 + const sal_uInt16 nMenuItemHeight = maLabelFont.GetHeight()*1.8;
517 + Size aWndSize = GetSizePixel();
519 + Point aPos1(nLeftMargin, nTopMargin);
520 + Size aSize1(aWndSize.Width() - nLeftMargin*2, nMenuItemHeight);
522 + rPos = aPos1;
523 + rPos.Y() += aSize1.Height()*nPos;
524 + rSize = aSize1;
527 +size_t ScMenuFloatingWindow::getEnclosingMenuItem(const Point& rPos) const
529 + size_t n = maMenuItems.size();
530 + for (size_t i = 0; i < n; ++i)
532 + Point aPos;
533 + Size aSize;
534 + getMenuItemPosSize(aPos, aSize, i);
535 + Rectangle aRect(aPos, aSize);
536 + if (aRect.IsInside(rPos))
537 + return i;
539 + return MENU_NOT_SELECTED;
542 +IMPL_LINK( ScMenuFloatingWindow, EndPopupHdl, void*, EMPTYARG )
544 + if (mbActionFired && mpParentMenu)
545 + mpParentMenu->EndPopupMode();
547 + return 0;
550 +// ============================================================================
552 ScDPFieldPopupWindow::Member::Member() :
553 mbVisible(true)
555 @@ -189,8 +711,19 @@ ScDPFieldPopupWindow::Member::Member() :
557 // ----------------------------------------------------------------------------
559 +ScDPFieldPopupWindow::CancelButton::CancelButton(ScDPFieldPopupWindow* pParent) :
560 + ::CancelButton(pParent), mpParent(pParent) {}
562 +void ScDPFieldPopupWindow::CancelButton::Click()
564 + mpParent->EndPopupMode();
565 + ::CancelButton::Click();
568 +// ----------------------------------------------------------------------------
570 ScDPFieldPopupWindow::ScDPFieldPopupWindow(Window* pParent) :
571 - FloatingWindow(pParent, (WB_SYSTEMFLOATWIN|WB_SYSTEMWINDOW|WB_NOBORDER)),
572 + ScMenuFloatingWindow(pParent),
573 maCheck0(this, 0),
574 maCheck1(this, 0),
575 maCheck2(this, 0),
576 @@ -201,8 +734,6 @@ ScDPFieldPopupWindow::ScDPFieldPopupWindow(Window* pParent) :
577 maCheck7(this, 0),
578 maCheck8(this, 0),
579 maCheck9(this, 0),
580 - maCheck10(this, 0),
581 - maCheck11(this, 0),
582 maScrollBar(this, WB_VERT),
583 maBtnOk(this),
584 maBtnCancel(this),
585 @@ -210,12 +741,13 @@ ScDPFieldPopupWindow::ScDPFieldPopupWindow(Window* pParent) :
586 mpOKAction(NULL),
587 mnScrollPos(0)
589 - SetOutputSizePixel(Size(150, 280));
590 + Point aPos;
591 + Size aSize;
592 + getSectionPosSize(aPos, aSize, WHOLE);
593 + SetOutputSizePixel(aSize);
594 Size aOutSize = GetOutputSizePixel();
596 - const StyleSettings& rStyle = GetSettings().GetStyleSettings();
598 - mpCheckPtr.reserve(12);
599 + mpCheckPtr.reserve(10);
600 mpCheckPtr.push_back(&maCheck0);
601 mpCheckPtr.push_back(&maCheck1);
602 mpCheckPtr.push_back(&maCheck2);
603 @@ -226,33 +758,27 @@ ScDPFieldPopupWindow::ScDPFieldPopupWindow(Window* pParent) :
604 mpCheckPtr.push_back(&maCheck7);
605 mpCheckPtr.push_back(&maCheck8);
606 mpCheckPtr.push_back(&maCheck9);
607 - mpCheckPtr.push_back(&maCheck10);
608 - mpCheckPtr.push_back(&maCheck11);
610 - Point aPos;
611 - Size aSize;
612 getSectionPosSize(aPos, aSize, FIRST_LISTITEM);
613 - Font aMemFont(rStyle.GetLabelFont());
614 - aMemFont.SetHeight(11);
615 for (vector<CheckBox*>::iterator itr = mpCheckPtr.begin(), itrEnd = mpCheckPtr.end();
616 itr != itrEnd; ++itr)
618 CheckBox* p = *itr;
619 p->SetPosSizePixel(aPos, aSize);
620 - p->SetFont(aMemFont);
621 + p->SetFont(getLabelFont());
622 p->SetClickHdl( LINK(this, ScDPFieldPopupWindow, CheckBoxHdl) );
623 - aPos.Y() += 18;
624 + aPos.Y() += aSize.Height() + 1;
627 getSectionPosSize(aPos, aSize, BTN_OK);
628 maBtnOk.SetPosSizePixel(aPos, aSize);
629 - maBtnOk.SetFont(aMemFont);
630 + maBtnOk.SetFont(getLabelFont());
631 maBtnOk.SetClickHdl( LINK(this, ScDPFieldPopupWindow, OKButtonHdl) );
632 maBtnOk.Show();
634 getSectionPosSize(aPos, aSize, BTN_CANCEL);
635 maBtnCancel.SetPosSizePixel(aPos, aSize);
636 - maBtnCancel.SetFont(aMemFont);
637 + maBtnCancel.SetFont(getLabelFont());
638 maBtnCancel.Show();
640 getSectionPosSize(aPos, aSize, SCROLL_BAR_V);
641 @@ -264,6 +790,10 @@ ScDPFieldPopupWindow::ScDPFieldPopupWindow(Window* pParent) :
642 maScrollBar.EnableDrag(true);
645 +ScDPFieldPopupWindow::~ScDPFieldPopupWindow()
649 vector<ScDPFieldPopupWindow::Member>& ScDPFieldPopupWindow::getMembers()
651 return maMembers;
652 @@ -271,61 +801,66 @@ vector<ScDPFieldPopupWindow::Member>& ScDPFieldPopupWindow::getMembers()
654 void ScDPFieldPopupWindow::getSectionPosSize(Point& rPos, Size& rSize, SectionType eType) const
656 - static const long nListBoxMargin = 5;
657 - static const long nBottomBtnAreaHeight = 50;
658 - static const long nInnerItemMargin = 5;
659 - static const long nScrollBarWidth = 17;
660 - static const long nBtnWidth = 60;
661 - static const long nBtnHeight = 22;
662 - static const long nBottomMargin = 10;
664 - const Size& rWndSize = GetSizePixel();
665 + const sal_uInt16 nListBoxMargin = 5;
666 + const sal_uInt16 nTopMargin = 5;
667 + const sal_uInt16 nMenuHeight = 60;
668 + const sal_uInt16 nBottomBtnAreaHeight = 50;
669 + const sal_uInt16 nInnerItemMargin = 5;
670 + const sal_uInt16 nScrollBarWidth = 17;
671 + const sal_uInt16 nBtnWidth = 60;
672 + const sal_uInt16 nBtnHeight = getLabelFont().GetHeight()*2;
673 + const sal_uInt16 nBottomMargin = 10;
674 + const sal_uInt16 nMenuListMargin = 20;
676 + Size aWndSize = Size(160, 330);
678 switch (eType)
680 case WHOLE:
682 rPos = Point(0, 0);
683 - rSize = rWndSize;
684 + rSize = aWndSize;
686 break;
687 case LISTBOX_AREA:
689 - rPos = Point(nListBoxMargin, nListBoxMargin);
690 + rPos = Point(nListBoxMargin, nTopMargin + nMenuHeight + nMenuListMargin);
691 rSize = Size(
692 - rWndSize.Width() - nListBoxMargin*2,
693 - rWndSize.Height() - nListBoxMargin - nBottomBtnAreaHeight);
694 + aWndSize.Width() - nListBoxMargin*2,
695 + aWndSize.Height() - nTopMargin - nMenuHeight - nMenuListMargin - nBottomBtnAreaHeight);
697 break;
698 case FIRST_LISTITEM:
700 rPos = Point(nListBoxMargin + nInnerItemMargin,
701 - nListBoxMargin + nInnerItemMargin);
702 + nTopMargin + nMenuHeight + nMenuListMargin + nInnerItemMargin);
703 rSize = Size(
704 - rWndSize.Width() - nListBoxMargin*2 - nInnerItemMargin - nScrollBarWidth - 10,
705 + aWndSize.Width() - nListBoxMargin*2 - nInnerItemMargin - nScrollBarWidth - 10,
706 17);
708 break;
709 case BTN_OK:
711 - long x = (rWndSize.Width() - nBtnWidth*2)/3;
712 - long y = rWndSize.Height() - nBottomMargin - nBtnHeight;
713 + long x = (aWndSize.Width() - nBtnWidth*2)/3;
714 + long y = aWndSize.Height() - nBottomMargin - nBtnHeight;
715 rPos = Point(x, y);
716 rSize = Size(nBtnWidth, nBtnHeight);
718 break;
719 case BTN_CANCEL:
721 - long x = (rWndSize.Width() - nBtnWidth*2)/3*2 + nBtnWidth;
722 - long y = rWndSize.Height() - nBottomMargin - nBtnHeight;
723 + long x = (aWndSize.Width() - nBtnWidth*2)/3*2 + nBtnWidth;
724 + long y = aWndSize.Height() - nBottomMargin - nBtnHeight;
725 rPos = Point(x, y);
726 rSize = Size(nBtnWidth, nBtnHeight);
728 break;
729 case SCROLL_BAR_V:
731 - long x = rWndSize.Width() - nListBoxMargin - nInnerItemMargin - nScrollBarWidth;
732 - long y = nListBoxMargin + nInnerItemMargin;
733 + long x = aWndSize.Width() - nListBoxMargin - nInnerItemMargin - nScrollBarWidth;
734 + long y = nTopMargin + nMenuHeight + nMenuListMargin + nInnerItemMargin;
735 rPos = Point(x, y);
736 - long h = rWndSize.Height() - nListBoxMargin - nBottomBtnAreaHeight - nInnerItemMargin*2;
737 + long h = aWndSize.Height() - nTopMargin - nMenuHeight - nMenuListMargin - nBottomBtnAreaHeight - nInnerItemMargin*2;
738 rSize = Size(nScrollBarWidth, h);
740 break;
741 @@ -377,31 +912,26 @@ IMPL_LINK( ScDPFieldPopupWindow, ScrollHdl, ScrollBar*, EMPTYARG )
742 return 0;
745 -ScDPFieldPopupWindow::~ScDPFieldPopupWindow()
746 +void ScDPFieldPopupWindow::MouseMove(const MouseEvent& rMEvt)
748 - EndPopupMode();
749 + ScMenuFloatingWindow::MouseMove(rMEvt);
751 + size_t nSelectedMenu = getSelectedMenuItem();
752 + if (nSelectedMenu == MENU_NOT_SELECTED)
753 + queueCloseSubMenu();
756 void ScDPFieldPopupWindow::Paint(const Rectangle& rRect)
758 - Window::Paint(rRect);
759 + ScMenuFloatingWindow::Paint(rRect);
761 const StyleSettings& rStyle = GetSettings().GetStyleSettings();
762 - Color aBackColor = rStyle.GetMenuColor();
763 - Color aBorderColor = rStyle.GetShadowColor();
764 Color aMemberBackColor = rStyle.GetFieldColor();
766 - Point aPos;
767 - Size aSize;
769 - // Window background
770 - SetFillColor(aBackColor);
771 - SetLineColor(aBorderColor);
772 - getSectionPosSize(aPos, aSize, WHOLE);
773 - DrawRect(Rectangle(aPos,aSize));
775 // Member list box background
776 SetFillColor(aMemberBackColor);
777 + Point aPos;
778 + Size aSize;
779 getSectionPosSize(aPos, aSize, LISTBOX_AREA);
780 DrawRect(Rectangle(aPos,aSize));
782 @@ -472,7 +1002,7 @@ ScDPFieldPopupWindow::ExtendedData* ScDPFieldPopupWindow::getExtendedData()
783 return mpExtendedData.get();
786 -void ScDPFieldPopupWindow::setOKAction(OKAction* p)
787 +void ScDPFieldPopupWindow::setOKAction(Action* p)
789 mpOKAction.reset(p);
791 diff --git sc/source/ui/cctrl/dpcontrol.src sc/source/ui/cctrl/dpcontrol.src
792 new file mode 100644
793 index 0000000..6c5fffe
794 --- /dev/null
795 +++ sc/source/ui/cctrl/dpcontrol.src
796 @@ -0,0 +1,49 @@
797 +/*************************************************************************
799 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
801 + * Copyright 2008 by Sun Microsystems, Inc.
803 + * OpenOffice.org - a multi-platform office productivity suite
805 + * $RCSfile: globstr.src,v $
806 + * $Revision: 1.74.96.1 $
808 + * This file is part of OpenOffice.org.
810 + * OpenOffice.org is free software: you can redistribute it and/or modify
811 + * it under the terms of the GNU Lesser General Public License version 3
812 + * only, as published by the Free Software Foundation.
814 + * OpenOffice.org is distributed in the hope that it will be useful,
815 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
816 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
817 + * GNU Lesser General Public License version 3 for more details
818 + * (a copy is included in the LICENSE file that accompanied this code).
820 + * You should have received a copy of the GNU Lesser General Public License
821 + * version 3 along with OpenOffice.org. If not, see
822 + * <http://www.openoffice.org/license.html>
823 + * for a copy of the LGPLv3 License.
825 + ************************************************************************/
827 +#include "dpcontrol.hrc"
829 +Resource RID_SC_DPCONTROL
831 + String STR_MENU_SORT_ASC
833 + Text [ en-US ] = "Sort Ascending" ;
834 + };
836 + String STR_MENU_SORT_DESC
838 + Text [ en-US ] = "Sort Descending" ;
839 + };
841 + String STR_MENU_SORT_CUSTOM
843 + Text [ en-US ] = "Custom Sort" ;
844 + };
846 diff --git sc/source/ui/cctrl/makefile.mk sc/source/ui/cctrl/makefile.mk
847 index 8e8add3..70095d8 100644
848 --- sc/source/ui/cctrl/makefile.mk
849 +++ sc/source/ui/cctrl/makefile.mk
850 @@ -45,7 +45,8 @@ LIBTARGET=NO
851 # --- Files --------------------------------------------------------
853 EXCEPTIONSFILES= \
854 - $(SLO)$/tbzoomsliderctrl.obj
855 + $(SLO)$/tbzoomsliderctrl.obj \
856 + $(SLO)$/dpcontrol.obj
858 SLOFILES = \
859 $(SLO)$/popmenu.obj \
860 @@ -55,6 +56,10 @@ SLOFILES = \
861 $(SLO)$/editfield.obj \
862 $(EXCEPTIONSFILES)
864 +SRS1NAME=$(TARGET)
865 +SRC1FILES = \
866 + dpcontrol.src
868 LIB1TARGET=$(SLB)$/$(TARGET).lib
869 LIB1OBJFILES= \
870 $(SLO)$/popmenu.obj \
871 @@ -63,6 +68,7 @@ LIB1OBJFILES= \
872 $(SLO)$/dpcontrol.obj \
873 $(SLO)$/tbzoomsliderctrl.obj
876 # --- Tagets -------------------------------------------------------
878 .INCLUDE : target.mk
879 diff --git sc/source/ui/inc/dbfunc.hxx sc/source/ui/inc/dbfunc.hxx
880 index d894e48..b494ae6 100644
881 --- sc/source/ui/inc/dbfunc.hxx
882 +++ sc/source/ui/inc/dbfunc.hxx
883 @@ -101,6 +101,7 @@ public:
884 void UngroupDataPilot();
885 void DataPilotInput( const ScAddress& rPos, const String& rString );
887 + bool DataPilotSort( const ScAddress& rPos, bool bAscending, sal_uInt16* pUserListId = NULL );
888 BOOL DataPilotMove( const ScRange& rSource, const ScAddress& rDest );
890 BOOL HasSelectionForDrillDown( USHORT& rOrientation );
891 diff --git sc/source/ui/inc/dpcontrol.hrc sc/source/ui/inc/dpcontrol.hrc
892 new file mode 100644
893 index 0000000..2ca698d
894 --- /dev/null
895 +++ sc/source/ui/inc/dpcontrol.hrc
896 @@ -0,0 +1,40 @@
897 +/*************************************************************************
899 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
900 + *
901 + * Copyright 2008 by Sun Microsystems, Inc.
903 + * OpenOffice.org - a multi-platform office productivity suite
905 + * $RCSfile: protectiondlg.hrc,v $
906 + * $Revision: 1.1.2.1 $
908 + * This file is part of OpenOffice.org.
910 + * OpenOffice.org is free software: you can redistribute it and/or modify
911 + * it under the terms of the GNU Lesser General Public License version 3
912 + * only, as published by the Free Software Foundation.
914 + * OpenOffice.org is distributed in the hope that it will be useful,
915 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
916 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
917 + * GNU Lesser General Public License version 3 for more details
918 + * (a copy is included in the LICENSE file that accompanied this code).
920 + * You should have received a copy of the GNU Lesser General Public License
921 + * version 3 along with OpenOffice.org. If not, see
922 + * <http://www.openoffice.org/license.html>
923 + * for a copy of the LGPLv3 License.
925 + ************************************************************************/
927 +#ifndef __DPCONTROL_HRC__
928 +#define __DPCONTROL_HRC__
930 +#include <sc.hrc>
932 +#define STR_MENU_SORT_ASC 1
933 +#define STR_MENU_SORT_DESC 2
934 +#define STR_MENU_SORT_CUSTOM 3
936 +#endif
937 diff --git sc/source/ui/inc/dpcontrol.hxx sc/source/ui/inc/dpcontrol.hxx
938 index 6a28354..64d56d3 100644
939 --- sc/source/ui/inc/dpcontrol.hxx
940 +++ sc/source/ui/inc/dpcontrol.hxx
941 @@ -36,7 +36,9 @@
942 #include "vcl/floatwin.hxx"
943 #include "vcl/button.hxx"
944 #include "vcl/scrbar.hxx"
945 +#include "vcl/timer.hxx"
947 +#include <boost/shared_ptr.hpp>
948 #include <memory>
949 #include <hash_map>
951 @@ -80,43 +82,128 @@ private:
953 // ============================================================================
955 -/**
956 - * This class implements a popup window for field button, for quick access
957 - * of hide-item list, and possibly more stuff related to field options.
958 - */
959 -class ScDPFieldPopupWindow : public FloatingWindow
960 +class ScMenuFloatingWindow : public FloatingWindow
962 public:
963 - class ButtonEvent
964 + /**
965 + * Action to perform when an event takes place. Create a sub-class of
966 + * this to implement the desired action.
967 + */
968 + class Action
970 public:
971 virtual void execute() = 0;
974 + explicit ScMenuFloatingWindow(Window* pParent);
975 + virtual ~ScMenuFloatingWindow();
977 + virtual void MouseMove(const MouseEvent& rMEvt);
978 + virtual void MouseButtonDown(const MouseEvent& rMEvt);
979 + virtual void MouseButtonUp(const MouseEvent& rMEvt);
980 + virtual void KeyInput(const KeyEvent& rKEvt);
981 + virtual void Paint(const Rectangle& rRect);
983 + void addMenuItem(const ::rtl::OUString& rText, bool bEnabled, Action* pAction);
984 + ScMenuFloatingWindow* addSubMenuItem(const ::rtl::OUString& rText, bool bEnabled);
986 +protected:
987 + void drawMenuItem(size_t nPos);
988 + void drawAllMenuItems();
989 + const Font& getLabelFont() const;
991 + void executeMenu(size_t nPos);
992 + void setSelectedMenuItem(size_t nPos, bool bSubMenuTimer = true);
993 + size_t getSelectedMenuItem() const;
994 + void queueLaunchSubMenu(size_t nPos, ScMenuFloatingWindow* pMenu);
995 + void queueCloseSubMenu();
996 + void launchSubMenu(bool bSetMenuPos);
997 + void endSubMenu();
999 +private:
1000 + struct SubMenuItem;
1001 + void handleMenuTimeout(SubMenuItem* pTimer);
1003 + enum NotificationType { SUBMENU_FOCUSED };
1004 + void notify(NotificationType eType);
1006 + void resetMenu(bool bSetMenuPos);
1007 + void resizeToFitMenuItems();
1008 + void selectMenuItem(size_t nPos, bool bSelected, bool bSubMenuTimer);
1009 + void highlightMenuItem(size_t nPos, bool bSelected);
1011 + void getMenuItemPosSize(Point& rPos, Size& rSize, size_t nPos) const;
1012 + size_t getEnclosingMenuItem(const Point& rPos) const;
1014 + DECL_LINK( EndPopupHdl, void* );
1016 +private:
1017 + struct MenuItem
1019 + ::rtl::OUString maText;
1020 + bool mbEnabled;
1022 + ::boost::shared_ptr<Action> mpAction;
1023 + ::boost::shared_ptr<ScMenuFloatingWindow> mpSubMenuWin;
1025 + MenuItem();
1026 + };
1028 + ::std::vector<MenuItem> maMenuItems;
1030 + struct SubMenuItem
1032 + Timer maTimer;
1033 + ScMenuFloatingWindow* mpSubMenu;
1034 + size_t mnMenuPos;
1036 + DECL_LINK( TimeoutHdl, void* );
1038 + SubMenuItem(ScMenuFloatingWindow* pParent);
1039 + void reset();
1041 + private:
1042 + ScMenuFloatingWindow* mpParent;
1043 + };
1044 + SubMenuItem maOpenTimer;
1045 + SubMenuItem maCloseTimer;
1047 + Font maLabelFont;
1049 + size_t mnSelectedMenu;
1050 + size_t mnClickedMenu;
1052 + ScMenuFloatingWindow* mpParentMenu;
1053 + ScMenuFloatingWindow* mpActiveSubMenu;
1055 + bool mbActionFired;
1058 +// ============================================================================
1060 +/**
1061 + * This class implements a popup window for field button, for quick access
1062 + * of hide-item list, and possibly more stuff related to field options.
1063 + */
1064 +class ScDPFieldPopupWindow : public ScMenuFloatingWindow
1066 +public:
1067 /**
1068 * Extended data that the client code may need to store. Create a
1069 * sub-class of this and store data there.
1071 struct ExtendedData {};
1073 - /**
1074 - * Action to perform when the OK button is pressed. Create a sub-class of
1075 - * this to implement the desired action.
1076 - */
1077 - class OKAction
1079 - public:
1080 - virtual void execute() = 0;
1081 - };
1083 explicit ScDPFieldPopupWindow(Window* pParent);
1084 virtual ~ScDPFieldPopupWindow();
1086 + virtual void MouseMove(const MouseEvent& rMEvt);
1087 virtual void Paint(const Rectangle& rRect);
1089 void setMemberSize(size_t n);
1090 void addMember(const ::rtl::OUString& rName, bool bVisible);
1091 void initMembers();
1093 void getResult(::std::hash_map< ::rtl::OUString, bool, ::rtl::OUStringHash>& rResult);
1094 void close(bool bOK);
1096 @@ -132,7 +219,7 @@ public:
1098 ExtendedData* getExtendedData();
1100 - void setOKAction(OKAction* p);
1101 + void setOKAction(Action* p);
1103 private:
1104 struct Member
1105 @@ -143,6 +230,17 @@ private:
1106 Member();
1109 + class CancelButton : public ::CancelButton
1111 + public:
1112 + CancelButton(ScDPFieldPopupWindow* pParent);
1114 + virtual void Click();
1116 + private:
1117 + ScDPFieldPopupWindow* mpParent;
1118 + };
1120 ::std::vector<Member>& getMembers();
1122 enum SectionType {
1123 @@ -173,8 +271,6 @@ private:
1124 CheckBox maCheck7;
1125 CheckBox maCheck8;
1126 CheckBox maCheck9;
1127 - CheckBox maCheck10;
1128 - CheckBox maCheck11;
1130 ScrollBar maScrollBar;
1132 @@ -185,9 +281,9 @@ private:
1134 ::std::vector<Member> maMembers;
1135 ::std::auto_ptr<ExtendedData> mpExtendedData;
1136 - ::std::auto_ptr<OKAction> mpOKAction;
1137 + ::std::auto_ptr<Action> mpOKAction;
1139 - size_t mnScrollPos;
1140 + size_t mnScrollPos;
1143 #endif
1144 diff --git sc/source/ui/view/dbfunc3.cxx sc/source/ui/view/dbfunc3.cxx
1145 index d83add1..f58d9b5 100644
1146 --- sc/source/ui/view/dbfunc3.cxx
1147 +++ sc/source/ui/view/dbfunc3.cxx
1148 @@ -81,9 +81,13 @@
1149 #include "patattr.hxx"
1150 #include "unonames.hxx"
1151 #include "cell.hxx"
1152 +#include "userlist.hxx"
1154 #include <hash_set>
1155 +#include <hash_map>
1156 #include <memory>
1157 +#include <list>
1158 +#include <vector>
1160 using namespace com::sun::star;
1161 using ::com::sun::star::uno::Any;
1162 @@ -94,8 +98,13 @@ using ::com::sun::star::beans::XPropertySet;
1163 using ::com::sun::star::container::XNameAccess;
1164 using ::com::sun::star::sheet::XDimensionsSupplier;
1165 using ::rtl::OUString;
1166 +using ::rtl::OUStringHash;
1167 using ::rtl::OUStringBuffer;
1168 using ::std::auto_ptr;
1169 +using ::std::list;
1170 +using ::std::vector;
1171 +using ::std::hash_map;
1172 +using ::std::hash_set;
1174 // STATIC DATA -----------------------------------------------------------
1176 @@ -1695,6 +1704,134 @@ void lcl_MoveToEnd( ScDPSaveDimension& rDim, const String& rItemName )
1177 // puts it to the end of the list even if it was in the list before.
1180 +bool ScDBFunc::DataPilotSort( const ScAddress& rPos, bool bAscending, sal_uInt16* pUserListId )
1182 + ScDocument* pDoc = GetViewData()->GetDocument();
1183 + ScDPObject* pDPObj = pDoc->GetDPAtCursor(rPos.Col(), rPos.Row(), rPos.Tab());
1184 + if (!pDPObj)
1185 + return false;
1187 + // We need to run this to get all members later.
1188 + pDPObj->BuildAllDimensionMembers();
1190 + USHORT nOrientation;
1191 + long nDimIndex = pDPObj->GetHeaderDim(rPos, nOrientation);
1192 + if (nDimIndex < 0)
1193 + // Invalid dimension index. Bail out.
1194 + return false;
1196 + BOOL bDataLayout;
1197 + ScDPSaveData* pSaveData = pDPObj->GetSaveData();
1198 + if (!pSaveData)
1199 + return false;
1201 + ScDPSaveData aNewSaveData(*pSaveData);
1202 + String aDimName = pDPObj->GetDimName(nDimIndex, bDataLayout);
1203 + ScDPSaveDimension* pSaveDim = aNewSaveData.GetDimensionByName(aDimName);
1204 + if (!pSaveDim)
1205 + return false;
1207 + typedef ScDPSaveDimension::MemberList MemList;
1208 + const MemList& rDimMembers = pSaveDim->GetMembers();
1209 + list<OUString> aMembers;
1210 + hash_set<OUString, ::rtl::OUStringHash> aMemberSet;
1211 + size_t nMemberCount = 0;
1212 + for (MemList::const_iterator itr = rDimMembers.begin(), itrEnd = rDimMembers.end();
1213 + itr != itrEnd; ++itr)
1215 + ScDPSaveMember* pMem = *itr;
1216 + aMembers.push_back(pMem->GetName());
1217 + aMemberSet.insert(pMem->GetName());
1218 + ++nMemberCount;
1221 + // Sort the member list in ascending order.
1222 + aMembers.sort();
1224 + // Collect and rank those custom sort strings that also exist in the member name list.
1226 + typedef hash_map<OUString, sal_uInt16, OUStringHash> UserSortMap;
1227 + UserSortMap aSubStrs;
1228 + sal_uInt16 nSubCount = 0;
1229 + if (pUserListId)
1231 + ScUserList* pUserList = ScGlobal::GetUserList();
1232 + if (!pUserList)
1233 + return false;
1236 + sal_uInt16 n = pUserList->GetCount();
1237 + if (!n || *pUserListId >= n)
1238 + return false;
1241 + ScUserListData* pData = static_cast<ScUserListData*>((*pUserList)[*pUserListId]);
1242 + if (pData)
1244 + sal_uInt16 n = pData->GetSubCount();
1245 + for (sal_uInt16 i = 0; i < n; ++i)
1247 + OUString aSub = pData->GetSubStr(i);
1248 + if (!aMemberSet.count(aSub))
1249 + // This string doesn't exist in the member name set. Don't add this.
1250 + continue;
1252 + aSubStrs.insert(UserSortMap::value_type(aSub, nSubCount++));
1257 + // Rank all members.
1259 + vector<OUString> aRankedNames(nMemberCount);
1260 + sal_uInt16 nCurStrId = 0;
1261 + for (list<OUString>::const_iterator itr = aMembers.begin(), itrEnd = aMembers.end();
1262 + itr != itrEnd; ++itr)
1264 + OUString aName = *itr;
1265 + sal_uInt16 nRank = 0;
1266 + UserSortMap::const_iterator itrSub = aSubStrs.find(aName);
1267 + if (itrSub == aSubStrs.end())
1268 + nRank = nSubCount + nCurStrId++;
1269 + else
1270 + nRank = itrSub->second;
1272 + if (!bAscending)
1273 + nRank = nMemberCount - nRank - 1;
1275 + aRankedNames[nRank] = aName;
1278 + // Re-order ScDPSaveMember instances with the new ranks.
1280 + for (vector<OUString>::const_iterator itr = aRankedNames.begin(), itrEnd = aRankedNames.end();
1281 + itr != itrEnd; ++itr)
1283 + const ScDPSaveMember* pOldMem = pSaveDim->GetExistingMemberByName(*itr);
1284 + if (!pOldMem)
1285 + // All members are supposed to be present.
1286 + continue;
1288 + ScDPSaveMember* pNewMem = new ScDPSaveMember(*pOldMem);
1289 + pSaveDim->AddMember(pNewMem);
1292 + // Set the sorting mode to manual for now. We may introduce a new sorting
1293 + // mode later on.
1295 + sheet::DataPilotFieldSortInfo aSortInfo;
1296 + aSortInfo.Mode = sheet::DataPilotFieldSortMode::MANUAL;
1297 + pSaveDim->SetSortInfo(&aSortInfo);
1299 + // Update the datapilot with the newly sorted field members.
1301 + auto_ptr<ScDPObject> pNewObj(new ScDPObject(*pDPObj));
1302 + pNewObj->SetSaveData(aNewSaveData);
1303 + ScDBDocFunc aFunc(*GetViewData()->GetDocShell());
1305 + return aFunc.DataPilotUpdate(pDPObj, pNewObj.get(), true, false);
1308 BOOL ScDBFunc::DataPilotMove( const ScRange& rSource, const ScAddress& rDest )
1310 BOOL bRet = FALSE;
1311 diff --git sc/source/ui/view/gridwin2.cxx sc/source/ui/view/gridwin2.cxx
1312 index 63ce024..72a6606 100644
1313 --- sc/source/ui/view/gridwin2.cxx
1314 +++ sc/source/ui/view/gridwin2.cxx
1315 @@ -56,6 +56,9 @@
1316 #include "dpshttab.hxx"
1317 #include "dbdocfun.hxx"
1318 #include "dpcontrol.hxx"
1319 +#include "dpcontrol.hrc"
1320 +#include "strload.hxx"
1321 +#include "userlist.hxx"
1323 #include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
1324 #include "scabstdlg.hxx" //CHINA001
1325 @@ -778,7 +781,7 @@ struct DPFieldPopupData : public ScDPFieldPopupWindow::ExtendedData
1326 long mnDim;
1329 -class DPFieldPopupOKAction : public ScDPFieldPopupWindow::OKAction
1330 +class DPFieldPopupOKAction : public ScMenuFloatingWindow::Action
1332 public:
1333 explicit DPFieldPopupOKAction(ScGridWindow* p) :
1334 @@ -792,6 +795,39 @@ private:
1335 ScGridWindow* mpGridWindow;
1338 +class PopupSortAction : public ScMenuFloatingWindow::Action
1340 +public:
1341 + enum SortType { ASCENDING, DESCENDING, CUSTOM };
1343 + explicit PopupSortAction(const ScAddress& rPos, SortType eType, sal_uInt16 nUserListIndex, ScTabViewShell* pViewShell) :
1344 + maPos(rPos), meType(eType), mnUserListIndex(nUserListIndex), mpViewShell(pViewShell) {}
1346 + virtual void execute()
1348 + switch (meType)
1350 + case ASCENDING:
1351 + mpViewShell->DataPilotSort(maPos, true);
1352 + break;
1353 + case DESCENDING:
1354 + mpViewShell->DataPilotSort(maPos, false);
1355 + break;
1356 + case CUSTOM:
1357 + mpViewShell->DataPilotSort(maPos, true, &mnUserListIndex);
1358 + break;
1359 + default:
1364 +private:
1365 + ScAddress maPos;
1366 + SortType meType;
1367 + sal_uInt16 mnUserListIndex;
1368 + ScTabViewShell* mpViewShell;
1373 void ScGridWindow::DPLaunchFieldPopupMenu(
1374 @@ -814,11 +850,48 @@ void ScGridWindow::DPLaunchFieldPopupMenu(
1375 mpDPFieldPopup.reset(new ScDPFieldPopupWindow(this));
1376 mpDPFieldPopup->setExtendedData(pDPData.release());
1377 mpDPFieldPopup->setOKAction(new DPFieldPopupOKAction(this));
1378 - sal_Int32 n = rLabelData.maMembers.getLength();
1379 - mpDPFieldPopup->setMemberSize(n);
1380 - for (sal_Int32 i = 0; i < n; ++i)
1381 - mpDPFieldPopup->addMember(rLabelData.maMembers[i], rLabelData.maVisible[i]);
1382 - mpDPFieldPopup->initMembers();
1384 + sal_Int32 n = rLabelData.maMembers.getLength();
1385 + mpDPFieldPopup->setMemberSize(n);
1386 + for (sal_Int32 i = 0; i < n; ++i)
1387 + mpDPFieldPopup->addMember(rLabelData.maMembers[i], rLabelData.maVisible[i]);
1388 + mpDPFieldPopup->initMembers();
1391 + vector<OUString> aUserSortNames;
1392 + ScUserList* pUserList = ScGlobal::GetUserList();
1393 + if (pUserList)
1395 + sal_uInt16 n = pUserList->GetCount();
1396 + aUserSortNames.reserve(n);
1397 + for (sal_uInt16 i = 0; i < n; ++i)
1399 + ScUserListData* pData = static_cast<ScUserListData*>((*pUserList)[i]);
1400 + aUserSortNames.push_back(pData->GetString());
1404 + // Populate the menus.
1405 + ScTabViewShell* pViewShell = pViewData->GetViewShell();
1406 + mpDPFieldPopup->addMenuItem(
1407 + ScRscStrLoader(RID_SC_DPCONTROL, STR_MENU_SORT_ASC).GetString(), true,
1408 + new PopupSortAction(rPos, PopupSortAction::ASCENDING, 0, pViewShell));
1409 + mpDPFieldPopup->addMenuItem(
1410 + ScRscStrLoader(RID_SC_DPCONTROL, STR_MENU_SORT_DESC).GetString(), true,
1411 + new PopupSortAction(rPos, PopupSortAction::DESCENDING, 0, pViewShell));
1412 + ScMenuFloatingWindow* pSubMenu = mpDPFieldPopup->addSubMenuItem(
1413 + ScRscStrLoader(RID_SC_DPCONTROL, STR_MENU_SORT_CUSTOM).GetString(), !aUserSortNames.empty());
1415 + if (pSubMenu && !aUserSortNames.empty())
1417 + size_t n = aUserSortNames.size();
1418 + for (size_t i = 0; i < n; ++i)
1419 + {
1420 + pSubMenu->addMenuItem(
1421 + aUserSortNames[i], true,
1422 + new PopupSortAction(rPos, PopupSortAction::CUSTOM, i, pViewShell));
1426 mpDPFieldPopup->SetPopupModeEndHdl( LINK(this, ScGridWindow, PopupModeEndHdl) );
1427 Rectangle aCellRect(rSrcPos, rSrcSize);
1428 diff --git sc/util/makefile.mk sc/util/makefile.mk
1429 index 88e0594..bdf4954 100644
1430 --- sc/util/makefile.mk
1431 +++ sc/util/makefile.mk
1432 @@ -58,6 +58,7 @@ RESLIB1LIST=\
1433 $(SRS)$/formdlgs.srs \
1434 $(SRS)$/pagedlg.srs \
1435 $(SRS)$/navipi.srs \
1436 + $(SRS)$/cctrl.srs \
1437 $(SOLARCOMMONRESDIR)$/sfx.srs
1439 RESLIB1NAME=sc