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, long nMinListWidth);
61  virtual ~SwFieldDialog() override;
62  virtual void dispose() override;
63 };
64 }
65 
66 SwFieldDialog::SwFieldDialog(SwEditWin* parent, sw::mark::IFieldmark* fieldBM, long nMinListWidth)
68  , m_xListBox(VclPtr<SwFieldListBox>::Create(this))
69  , m_pFieldmark(fieldBM)
70 {
71  weld::TreeView& rTreeView = m_xListBox->get_widget();
72 
73  if (fieldBM != nullptr)
74  {
75  const sw::mark::IFieldmark::parameter_map_t* const pParameters = fieldBM->GetParameters();
76 
77  sw::mark::IFieldmark::parameter_map_t::const_iterator pListEntries
78  = pParameters->find(ODF_FORMDROPDOWN_LISTENTRY);
79  css::uno::Sequence<OUString> vListEntries;
80  if (pListEntries != pParameters->end())
81  {
82  pListEntries->second >>= vListEntries;
83  for (OUString const& i : std::as_const(vListEntries))
84  rTreeView.append_text(i);
85  }
86 
87  if (!vListEntries.hasElements())
88  {
89  rTreeView.append_text(SwResId(STR_DROP_DOWN_EMPTY_LIST));
90  }
91 
92  // Select the current one
93  sw::mark::IFieldmark::parameter_map_t::const_iterator pResult
94  = pParameters->find(ODF_FORMDROPDOWN_RESULT);
95  if (pResult != pParameters->end())
96  {
97  sal_Int32 nSelection = -1;
98  pResult->second >>= nSelection;
99  rTreeView.set_cursor(nSelection);
100  rTreeView.select(nSelection);
101  }
102  }
103 
104  auto nHeight = rTreeView.get_height_rows(
105  std::min<int>(Application::GetSettings().GetStyleSettings().GetListBoxMaximumLineCount(),
106  rTreeView.n_children()));
107  rTreeView.set_size_request(-1, nHeight);
108  Size lbSize(rTreeView.get_preferred_size());
109  lbSize.AdjustWidth(4);
110  lbSize.AdjustHeight(4);
111  lbSize.setWidth(std::max(lbSize.Width(), nMinListWidth));
112  m_xListBox->SetSizePixel(lbSize);
113  rTreeView.connect_row_activated(LINK(this, SwFieldDialog, MyListBoxHandler));
114  rTreeView.connect_key_press(LINK(this, SwFieldDialog, KeyInputHdl));
115  m_xListBox->Show();
116 
117  rTreeView.grab_focus();
118 
119  SetSizePixel(lbSize);
120 }
121 
122 SwFieldDialog::~SwFieldDialog() { disposeOnce(); }
123 
125 {
126  m_xListBox.disposeAndClear();
128 }
129 
130 IMPL_LINK(SwFieldDialog, MyListBoxHandler, weld::TreeView&, rBox, bool)
131 {
132  OUString sSelection = rBox.get_selected_text();
133  if (sSelection == SwResId(STR_DROP_DOWN_EMPTY_LIST))
134  {
135  EndPopupMode();
136  return true;
137  }
138 
139  sal_Int32 nSelection = rBox.get_selected_index();
140  if (nSelection >= 0)
141  {
142  (*m_pFieldmark->GetParameters())[ODF_FORMDROPDOWN_RESULT] <<= nSelection;
143  m_pFieldmark->Invalidate();
144  SwView& rView = static_cast<SwEditWin*>(GetParent())->GetView();
145  rView.GetDocShell()->SetModified();
146  }
147 
148  EndPopupMode();
149 
150  return true;
151 }
152 
153 IMPL_STATIC_LINK(SwFieldDialog, KeyInputHdl, const KeyEvent&, rKeyEvent, bool)
154 {
155  bool bDone = false;
156  vcl::KeyCode aCode = rKeyEvent.GetKeyCode();
157  // nowhere to tab to
158  if (aCode.GetCode() == KEY_TAB)
159  bDone = true;
160  return bDone;
161 }
162 
164  sw::mark::DropDownFieldmark& rFieldmark)
165  : FormFieldButton(pEditWin, rFieldmark)
166 {
167 }
168 
170 
172 {
173  m_pFieldPopup = VclPtr<SwFieldDialog>::Create(static_cast<SwEditWin*>(GetParent()),
175 }
176 
177 /* 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:1377
std::map< OUString, css::uno::Any > parameter_map_t
Definition: IMark.hxx:94
WinBits const WB_SYSTEMWINDOW
long AdjustWidth(long n)
sw::mark::Fieldmark & m_rFieldmark
void Create(SwFormatVertOrient &rItem, SvStream &rStrm, sal_uInt16 nVersionAbusedAsSize)
Definition: legacyitem.cxx:32
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:1189
OUString SwResId(const char *pId)
Definition: swmodule.cxx:178
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:1107
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
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:291
Definition: view.hxx:144
constexpr sal_uInt16 KEY_TAB