LibreOffice Module sw (master)  1
DropDownFormFieldButton.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  */
9 
11 #include <edtwin.hxx>
12 #include <bookmrk.hxx>
13 #include <vcl/event.hxx>
14 #include <vcl/floatwin.hxx>
16 #include <vcl/settings.hxx>
17 #include <vcl/svapp.hxx>
18 #include <xmloff/odffields.hxx>
19 #include <IMark.hxx>
20 #include <view.hxx>
21 #include <docsh.hxx>
22 #include <strings.hrc>
23 
24 namespace
25 {
26 class SwFieldListBox final : public InterimItemWindow
27 {
28 private:
29  std::unique_ptr<weld::TreeView> m_xTreeView;
30 
31 public:
32  SwFieldListBox(vcl::Window* pParent)
33  : InterimItemWindow(pParent, "modules/swriter/ui/formdropdown.ui", "FormDropDown")
34  , m_xTreeView(m_xBuilder->weld_tree_view("list"))
35  {
36  }
37  weld::TreeView& get_widget() { return *m_xTreeView; }
38  virtual ~SwFieldListBox() override { disposeOnce(); }
39  virtual void dispose() override
40  {
41  m_xTreeView.reset();
43  }
44 };
45 
50 class SwFieldDialog : public FloatingWindow
51 {
52 private:
53  VclPtr<SwFieldListBox> m_xListBox;
55 
56  DECL_LINK(MyListBoxHandler, weld::TreeView&, bool);
57  DECL_STATIC_LINK(SwFieldDialog, KeyInputHdl, const KeyEvent&, bool);
58 
59 public:
60  SwFieldDialog(SwEditWin* parent, sw::mark::IFieldmark* fieldBM, tools::Long nMinListWidth);
61  virtual ~SwFieldDialog() override;
62  virtual void dispose() override;
63 };
64 }
65 
66 SwFieldDialog::SwFieldDialog(SwEditWin* parent, sw::mark::IFieldmark* fieldBM,
67  tools::Long nMinListWidth)
69  , m_xListBox(VclPtr<SwFieldListBox>::Create(this))
70  , m_pFieldmark(fieldBM)
71 {
72  weld::TreeView& rTreeView = m_xListBox->get_widget();
73 
74  if (fieldBM != nullptr)
75  {
76  const sw::mark::IFieldmark::parameter_map_t* const pParameters = fieldBM->GetParameters();
77 
78  sw::mark::IFieldmark::parameter_map_t::const_iterator pListEntries
79  = pParameters->find(ODF_FORMDROPDOWN_LISTENTRY);
80  css::uno::Sequence<OUString> vListEntries;
81  if (pListEntries != pParameters->end())
82  {
83  pListEntries->second >>= vListEntries;
84  for (OUString const& i : std::as_const(vListEntries))
85  rTreeView.append_text(i);
86  }
87 
88  if (!vListEntries.hasElements())
89  {
90  rTreeView.append_text(SwResId(STR_DROP_DOWN_EMPTY_LIST));
91  }
92 
93  // Select the current one
94  sw::mark::IFieldmark::parameter_map_t::const_iterator pResult
95  = pParameters->find(ODF_FORMDROPDOWN_RESULT);
96  if (pResult != pParameters->end())
97  {
98  sal_Int32 nSelection = -1;
99  pResult->second >>= nSelection;
100  rTreeView.set_cursor(nSelection);
101  rTreeView.select(nSelection);
102  }
103  }
104 
105  auto nHeight = rTreeView.get_height_rows(
106  std::min<int>(Application::GetSettings().GetStyleSettings().GetListBoxMaximumLineCount(),
107  rTreeView.n_children()));
108  rTreeView.set_size_request(-1, nHeight);
109  Size lbSize(rTreeView.get_preferred_size());
110  lbSize.AdjustWidth(4);
111  lbSize.AdjustHeight(4);
112  lbSize.setWidth(std::max(lbSize.Width(), nMinListWidth));
113  m_xListBox->SetSizePixel(lbSize);
114  rTreeView.connect_row_activated(LINK(this, SwFieldDialog, MyListBoxHandler));
115  rTreeView.connect_key_press(LINK(this, SwFieldDialog, KeyInputHdl));
116  m_xListBox->Show();
117 
118  rTreeView.grab_focus();
119 
120  SetSizePixel(lbSize);
121 }
122 
123 SwFieldDialog::~SwFieldDialog() { disposeOnce(); }
124 
126 {
127  m_xListBox.disposeAndClear();
129 }
130 
131 IMPL_LINK(SwFieldDialog, MyListBoxHandler, weld::TreeView&, rBox, bool)
132 {
133  OUString sSelection = rBox.get_selected_text();
134  if (sSelection == SwResId(STR_DROP_DOWN_EMPTY_LIST))
135  {
136  EndPopupMode();
137  return true;
138  }
139 
140  sal_Int32 nSelection = rBox.get_selected_index();
141  if (nSelection >= 0)
142  {
143  (*m_pFieldmark->GetParameters())[ODF_FORMDROPDOWN_RESULT] <<= nSelection;
144  m_pFieldmark->Invalidate();
145  SwView& rView = static_cast<SwEditWin*>(GetParent())->GetView();
146  rView.GetDocShell()->SetModified();
147  }
148 
149  EndPopupMode();
150 
151  return true;
152 }
153 
154 IMPL_STATIC_LINK(SwFieldDialog, KeyInputHdl, const KeyEvent&, rKeyEvent, bool)
155 {
156  bool bDone = false;
157  vcl::KeyCode aCode = rKeyEvent.GetKeyCode();
158  // nowhere to tab to
159  if (aCode.GetCode() == KEY_TAB)
160  bDone = true;
161  return bDone;
162 }
163 
165  sw::mark::DropDownFieldmark& rFieldmark)
166  : FormFieldButton(pEditWin, rFieldmark)
167 {
168 }
169 
171 
173 {
174  m_pFieldPopup = VclPtr<SwFieldDialog>::Create(static_cast<SwEditWin*>(GetParent()),
176 }
177 
178 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
virtual ~DropDownFormFieldButton() override
virtual void SetModified(bool=true) override
Definition: docsh2.cxx:1378
std::map< OUString, css::uno::Any > parameter_map_t
Definition: IMark.hxx:94
WinBits const WB_SYSTEMWINDOW
sw::mark::Fieldmark & m_rFieldmark
void Create(SwFormatVertOrient &rItem, SvStream &rStrm, sal_uInt16 nVersionAbusedAsSize)
Definition: legacyitem.cxx:32
long Long
virtual void InitPopup() override
static const AllSettings & GetSettings()
virtual Size GetSizePixel() const
sal_uInt16 GetCode() const
#define ODF_FORMDROPDOWN_RESULT
void append_text(const OUString &rStr)
VclPtr< FloatingWindow > m_pFieldPopup
IMPL_LINK(DocumentStatisticsManager, DoIdleStatsUpdate, Timer *, pIdle, void)
virtual int n_children() const =0
virtual parameter_map_t * GetParameters()=0
void connect_row_activated(const Link< TreeView &, bool > &rLink)
This button is shown when the cursor is on a form field with drop-down capability.
Window class for the Writer edit area, this is the one handling mouse and keyboard events and doing t...
Definition: edtwin.hxx:58
std::unique_ptr< Fieldmark > m_pFieldmark
Definition: docbm.cxx:1204
OUString SwResId(const char *pId)
Definition: swmodule.cxx:165
vcl::Window * GetParent() const
virtual Size get_preferred_size() const =0
virtual void connect_key_press(const Link< const KeyEvent &, bool > &rLink)
SwDocShell * GetDocShell()
Definition: view.cxx:1109
virtual void select(int pos)=0
DropDownFormFieldButton(SwEditWin *pEditWin, sw::mark::DropDownFieldmark &rFieldMark)
WinBits const WB_BORDER
virtual void grab_focus()=0
virtual void dispose() override
tools::Long AdjustWidth(tools::Long n)
static VclPtr< reference_type > Create(Arg &&...arg)
virtual int get_height_rows(int nRows) const =0
virtual void set_cursor(int pos)=0
virtual void set_size_request(int nWidth, int nHeight)=0
virtual void dispose() override
Fieldmark representing a drop-down form field.
Definition: bookmrk.hxx:282
Definition: view.hxx:144
constexpr sal_uInt16 KEY_TAB