1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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  * This file incorporates work covered by the following license notice:
10  *
11  *   Licensed to the Apache Software Foundation (ASF) under one or more
12  *   contributor license agreements. See the NOTICE file distributed
13  *   with this work for additional information regarding copyright
14  *   ownership. The ASF licenses this file to you under the Apache
15  *   License, Version 2.0 (the "License"); you may not use this file
16  *   except in compliance with the License. You may obtain a copy of
17  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #ifndef INCLUDED_BASCTL_SOURCE_INC_BASTYPE2_HXX
21 #define INCLUDED_BASCTL_SOURCE_INC_BASTYPE2_HXX
22 
23 #include <sal/config.h>
24 
25 #include <memory>
26 
27 #include "doceventnotifier.hxx"
28 
29 #include <vcl/treelistbox.hxx>
30 #include <vcl/weld.hxx>
31 #include <basic/sbstar.hxx>
32 #include "sbxitem.hxx"
33 #include "basobj.hxx"
34 #include <o3tl/typed_flags_set.hxx>
35 
36 class SbModule;
37 class SvTreeListEntry;
38 class SbxVariable;
39 
40 enum class BrowseMode
41 {
42     Modules  = 0x01,
43     Subs     = 0x02,
44     Dialogs  = 0x04,
45     All      = Modules | Subs | Dialogs,
46 };
47 namespace o3tl {
48     template<> struct typed_flags<BrowseMode> : is_typed_flags<BrowseMode, 0x7> {};
49 }
50 
51 namespace basctl
52 {
53 using namespace ::com::sun::star::uno;
54 
55 enum EntryType
56 {
57     OBJ_TYPE_UNKNOWN,
58     OBJ_TYPE_DOCUMENT,
59     OBJ_TYPE_LIBRARY,
60     OBJ_TYPE_MODULE,
61     OBJ_TYPE_DIALOG,
62     OBJ_TYPE_METHOD,
63     OBJ_TYPE_DOCUMENT_OBJECTS,
64     OBJ_TYPE_USERFORMS,
65     OBJ_TYPE_NORMAL_MODULES,
66     OBJ_TYPE_CLASS_MODULES
67 };
68 
69 class Entry
70 {
71 private:
72     EntryType m_eType;
73 
74 public:
Entry(EntryType eType)75     explicit Entry(EntryType eType)
76         : m_eType(eType)
77     {
78     }
79 
80     virtual ~Entry();
81 
82     Entry(Entry const &) = default;
83     Entry(Entry &&) = default;
84     Entry & operator =(Entry const &) = default;
85     Entry & operator =(Entry &&) = default;
86 
GetType() const87     EntryType GetType () const { return m_eType; }
88 };
89 
90 class DocumentEntry : public Entry
91 {
92 private:
93     ScriptDocument      m_aDocument;
94     LibraryLocation     m_eLocation;
95 
96 public:
97     DocumentEntry (
98         ScriptDocument const& rDocument,
99         LibraryLocation eLocation,
100         EntryType eType = OBJ_TYPE_DOCUMENT
101     );
102     virtual ~DocumentEntry () override;
103 
GetDocument() const104     ScriptDocument const& GetDocument() const { return m_aDocument; }
GetLocation() const105     LibraryLocation GetLocation() const { return m_eLocation; }
106 };
107 
108 class LibEntry : public DocumentEntry
109 {
110 private:
111     OUString m_aLibName;
112 
113 public:
114     LibEntry (
115         ScriptDocument const& rDocument,
116         LibraryLocation eLocation,
117         OUString       const& rLibName
118     );
119     virtual ~LibEntry () override;
120 
GetLibName() const121     OUString const& GetLibName () const { return m_aLibName; }
122 };
123 
124 class EntryDescriptor
125 {
126     ScriptDocument   m_aDocument;
127     LibraryLocation  m_eLocation;
128     OUString         m_aLibName;
129     OUString         m_aLibSubName;  // for vba entry:  Document Objects, Class Modules, Forms and Normal Modules
130     OUString         m_aName;
131     OUString         m_aMethodName;
132     EntryType        m_eType;
133 
134 public:
135     EntryDescriptor ();
136     EntryDescriptor (
137         ScriptDocument const& rDocument,
138         LibraryLocation eLocation,
139         OUString      const& rLibName,
140         OUString      const& rLibSubName,
141         OUString      const& rName,
142         EntryType eType
143     );
144     EntryDescriptor (
145         ScriptDocument const& rDocument,
146         LibraryLocation eLocation,
147         OUString      const& rLibName,
148         OUString      const& rLibSubName,
149         OUString      const& rName,
150         OUString      const& rMethodName,
151         EntryType eType
152     );
153 
GetDocument() const154     ScriptDocument const&   GetDocument()   const { return m_aDocument; }
GetLocation() const155     LibraryLocation         GetLocation()   const { return m_eLocation; }
156 
GetLibName() const157     const OUString&         GetLibName()    const { return m_aLibName; }
GetLibSubName() const158     const OUString&         GetLibSubName() const { return m_aLibSubName; }
GetName() const159     const OUString&         GetName()       const { return m_aName; }
GetMethodName() const160     const OUString&         GetMethodName() const { return m_aMethodName; }
SetMethodName(const OUString & aMethodName)161     void                    SetMethodName( const OUString& aMethodName ) { m_aMethodName = aMethodName; }
162 
GetType() const163     EntryType               GetType() const { return m_eType; }
SetType(EntryType eType)164     void                    SetType( EntryType eType ) { m_eType = eType; }
165 };
166 
167 
168 /*
169     Classification of types and pointers in the Entries:
170 
171     OBJ_TYPE_DOCUMENT        DocumentEntry
172     OBJ_TYPE_LIBRARY         Entry
173     OBJ_TYPE_MODULE          Entry
174     OBJ_TYPE_DIALOG          Entry
175     OBJ_TYPE_METHOD          Entry
176 
177 */
178 
179 class TreeListBox : public SvTreeListBox, public DocumentEventListener
180 {
181 private:
182     DocumentEventNotifier m_aNotifier;
183     void            SetEntryBitmaps( SvTreeListEntry * pEntry, const Image& rImage );
184     virtual void    MouseButtonDown(const MouseEvent& rMEvt) override;
185 
186 protected:
187     virtual void            RequestingChildren( SvTreeListEntry* pParent ) override;
188     virtual void            ExpandedHdl() override;
189     virtual SvTreeListEntry*    CloneEntry( SvTreeListEntry* pSource ) override;
190     virtual bool            ExpandingHdl() override;
191     virtual void            KeyInput( const KeyEvent& rEvt ) override;
192 
193     bool                    OpenCurrent();
194     void                    ImpCreateLibEntries( SvTreeListEntry* pShellRootEntry, const ScriptDocument& rDocument, LibraryLocation eLocation );
195     void                    ImpCreateLibSubEntries( SvTreeListEntry* pLibRootEntry, const ScriptDocument& rDocument, const OUString& rLibName );
196     void                    ImpCreateLibSubEntriesInVBAMode( SvTreeListEntry* pLibRootEntry, const ScriptDocument& rDocument, const OUString& rLibName );
197     void                    ImpCreateLibSubSubEntriesInVBAMode( SvTreeListEntry* pLibSubRootEntry, const ScriptDocument& rDocument, const OUString& rLibName );
198     SvTreeListEntry*            ImpFindEntry( SvTreeListEntry* pParent, const OUString& rText );
199 
200     // DocumentEventListener
201     virtual void onDocumentCreated( const ScriptDocument& _rDocument ) override;
202     virtual void onDocumentOpened( const ScriptDocument& _rDocument ) override;
203     virtual void onDocumentSave( const ScriptDocument& _rDocument ) override;
204     virtual void onDocumentSaveDone( const ScriptDocument& _rDocument ) override;
205     virtual void onDocumentSaveAs( const ScriptDocument& _rDocument ) override;
206     virtual void onDocumentSaveAsDone( const ScriptDocument& _rDocument ) override;
207     virtual void onDocumentClosed( const ScriptDocument& _rDocument ) override;
208     virtual void onDocumentTitleChanged( const ScriptDocument& _rDocument ) override;
209     virtual void onDocumentModeChanged( const ScriptDocument& _rDocument ) override;
210 
211 public:
212     TreeListBox(vcl::Window* pParent, WinBits nStyle);
213     virtual ~TreeListBox() override;
214     virtual void    dispose() override;
215 
216     void            ScanEntry( const ScriptDocument& rDocument, LibraryLocation eLocation );
217     void            ScanAllEntries();
218     void            UpdateEntries();
219 
220     SvTreeListEntry*    FindRootEntry( const ScriptDocument& rDocument, LibraryLocation eLocation );
221     SvTreeListEntry*    FindEntry( SvTreeListEntry* pParent, const OUString& rText, EntryType eType );
222 
223     EntryDescriptor GetEntryDescriptor( SvTreeListEntry* pEntry );
224 
225     static ItemType ConvertType (EntryType eType);
226     bool            IsValidEntry( SvTreeListEntry* pEntry );
227 
228     void FillTreeListBox( SvTreeListEntry* pRootEntry, const Sequence< OUString >& rNames,
229                           const EntryType& eType, const OUString& aBmpMacro );
230     SvTreeListEntry*    AddEntry(
231         const OUString& rText, const Image& rImage,
232         SvTreeListEntry* pParent, bool bChildrenOnDemand,
233         std::unique_ptr<Entry> && aUserData
234     );
235     void            RemoveEntry (SvTreeListEntry const *);
236     void            RemoveEntry (ScriptDocument const&);
237 
238     static OUString GetRootEntryName( const ScriptDocument& rDocument, LibraryLocation eLocation );
239     static void     GetRootEntryBitmaps( const ScriptDocument& rDocument, Image& rImage );
240 
241     void            SetCurrentEntry (EntryDescriptor const &);
242 };
243 
244 class SbTreeListBox : public DocumentEventListener
245 {
246 private:
247     std::unique_ptr<weld::TreeView> m_xControl;
248     std::unique_ptr<weld::TreeIter> m_xIter;
249     weld::Window* m_pTopLevel;
250     BrowseMode nMode;
251     DocumentEventNotifier m_aNotifier;
252     void            SetEntryBitmaps(const weld::TreeIter& rIter, const OUString& rImage);
253 
254 protected:
255     DECL_LINK(RequestingChildrenHdl, const weld::TreeIter&, bool);
256     DECL_LINK(OpenCurrentHdl, weld::TreeView&, bool);
257     void                    ImpCreateLibEntries(const weld::TreeIter& rShellRootEntry, const ScriptDocument& rDocument, LibraryLocation eLocation);
258     void                    ImpCreateLibSubEntries(const weld::TreeIter& rLibRootEntry, const ScriptDocument& rDocument, const OUString& rLibName);
259     void                    ImpCreateLibSubEntriesInVBAMode(const weld::TreeIter& rLibRootEntry, const ScriptDocument& rDocument, const OUString& rLibName );
260     void                    ImpCreateLibSubSubEntriesInVBAMode(const weld::TreeIter& rLibRootEntry, const ScriptDocument& rDocument, const OUString& rLibName);
261     bool                    ImpFindEntry(weld::TreeIter& rIter, const OUString& rText);
262 
263     // DocumentEventListener
264     virtual void onDocumentCreated( const ScriptDocument& _rDocument ) override;
265     virtual void onDocumentOpened( const ScriptDocument& _rDocument ) override;
266     virtual void onDocumentSave( const ScriptDocument& _rDocument ) override;
267     virtual void onDocumentSaveDone( const ScriptDocument& _rDocument ) override;
268     virtual void onDocumentSaveAs( const ScriptDocument& _rDocument ) override;
269     virtual void onDocumentSaveAsDone( const ScriptDocument& _rDocument ) override;
270     virtual void onDocumentClosed( const ScriptDocument& _rDocument ) override;
271     virtual void onDocumentTitleChanged( const ScriptDocument& _rDocument ) override;
272     virtual void onDocumentModeChanged( const ScriptDocument& _rDocument ) override;
273 
274 public:
275     SbTreeListBox(std::unique_ptr<weld::TreeView> xControl, weld::Window* pTopLevel);
276     virtual ~SbTreeListBox() override;
277 
278     void            ScanEntry( const ScriptDocument& rDocument, LibraryLocation eLocation );
279     void            ScanAllEntries();
280     void            UpdateEntries();
281 
282     bool            IsEntryProtected(const weld::TreeIter* pEntry);
283 
SetMode(BrowseMode nM)284     void            SetMode( BrowseMode nM ) { nMode = nM; }
GetMode() const285     BrowseMode      GetMode() const { return nMode; }
286 
287     SbModule*       FindModule(const weld::TreeIter* pEntry);
288     SbxVariable*    FindVariable(const weld::TreeIter* pEntry);
289     bool            FindRootEntry(const ScriptDocument& rDocument, LibraryLocation eLocation, weld::TreeIter& rIter);
290     bool            FindEntry(const OUString& rText, EntryType eType, weld::TreeIter& rIter);
291     EntryDescriptor GetEntryDescriptor(const weld::TreeIter* pEntry);
292 
293     static ItemType ConvertType (EntryType eType);
294     bool            IsValidEntry(weld::TreeIter& rEntry);
295     void AddEntry(const OUString& rText, const OUString& rImage,
296                   const weld::TreeIter* pParent, bool bChildrenOnDemand,
297                   std::unique_ptr<Entry>&& rUserData,
298                   weld::TreeIter* pRet = nullptr);
299 
connect_changed(const Link<weld::TreeView &,void> & rLink)300     void connect_changed(const Link<weld::TreeView&, void>& rLink) { m_xControl->connect_changed(rLink); }
make_iterator(const weld::TreeIter * pIter=nullptr) const301     std::unique_ptr<weld::TreeIter> make_iterator(const weld::TreeIter* pIter = nullptr) const { return m_xControl->make_iterator(pIter); }
copy_iterator(const weld::TreeIter & rSource,weld::TreeIter & rDest) const302     void copy_iterator(const weld::TreeIter& rSource, weld::TreeIter& rDest) const { m_xControl->copy_iterator(rSource, rDest); }
get_selected(weld::TreeIter * pIter) const303     bool get_selected(weld::TreeIter* pIter) const { return m_xControl->get_selected(pIter); }
select(const weld::TreeIter & rIter)304     void select(const weld::TreeIter& rIter) { m_xControl->select(rIter); }
unselect(const weld::TreeIter & rIter)305     void unselect(const weld::TreeIter& rIter) { m_xControl->unselect(rIter); }
remove(const weld::TreeIter & rIter)306     void remove(const weld::TreeIter& rIter) { m_xControl->remove(rIter); }
get_cursor(weld::TreeIter * pIter) const307     bool get_cursor(weld::TreeIter* pIter) const { return m_xControl->get_cursor(pIter); }
set_cursor(const weld::TreeIter & rIter)308     void set_cursor(const weld::TreeIter& rIter) { m_xControl->set_cursor(rIter); }
get_text(const weld::TreeIter & rIter) const309     OUString get_text(const weld::TreeIter& rIter) const { return m_xControl->get_text(rIter); }
set_text(const weld::TreeIter & rIter,const OUString & rText)310     void set_text(const weld::TreeIter& rIter, const OUString& rText) { m_xControl->set_text(rIter, rText); }
get_id(const weld::TreeIter & rIter) const311     OUString get_id(const weld::TreeIter& rIter) const { return m_xControl->get_id(rIter); }
get_iter_first(weld::TreeIter & rIter) const312     bool get_iter_first(weld::TreeIter& rIter) const { return m_xControl->get_iter_first(rIter); }
iter_next_sibling(weld::TreeIter & rIter) const313     bool iter_next_sibling(weld::TreeIter& rIter) const { return m_xControl->iter_next_sibling(rIter); }
iter_children(weld::TreeIter & rIter) const314     bool iter_children(weld::TreeIter& rIter) const { return m_xControl->iter_children(rIter); }
iter_parent(weld::TreeIter & rIter) const315     bool iter_parent(weld::TreeIter& rIter) const { return m_xControl->iter_parent(rIter); }
get_iter_depth(const weld::TreeIter & rIter) const316     int get_iter_depth(const weld::TreeIter& rIter) const { return m_xControl->get_iter_depth(rIter); }
get_row_expanded(const weld::TreeIter & rIter) const317     bool get_row_expanded(const weld::TreeIter& rIter) const { return m_xControl->get_row_expanded(rIter); }
expand_row(const weld::TreeIter & rIter)318     void expand_row(const weld::TreeIter& rIter) { m_xControl->expand_row(rIter); }
set_size_request(int nWidth,int nHeight)319     void set_size_request(int nWidth, int nHeight) { m_xControl->set_size_request(nWidth, nHeight); }
get_approximate_digit_width() const320     float get_approximate_digit_width() const { return m_xControl->get_approximate_digit_width(); }
get_height_rows(int nRows) const321     int get_height_rows(int nRows) const { return m_xControl->get_height_rows(nRows); }
get_iter_index_in_parent(const weld::TreeIter & rIter) const322     int get_iter_index_in_parent(const weld::TreeIter& rIter) const { return m_xControl->get_iter_index_in_parent(rIter); }
connect_editing(const Link<const weld::TreeIter &,bool> & rStartLink,const Link<const std::pair<const weld::TreeIter &,OUString> &,bool> & rEndLink)323     void connect_editing(const Link<const weld::TreeIter&, bool>& rStartLink,
324                          const Link<const std::pair<const weld::TreeIter&, OUString>&, bool>& rEndLink)
325     {
326         m_xControl->connect_editing(rStartLink, rEndLink);
327     }
328 
make_sorted()329     void make_sorted() { m_xControl->make_sorted(); };
make_unsorted()330     void make_unsorted() { m_xControl->make_unsorted(); }
get_sort_order() const331     bool get_sort_order() const { return m_xControl->get_sort_order(); }
set_sort_order(bool bAscending)332     void set_sort_order(bool bAscending) { m_xControl->set_sort_order(bAscending); }
333 
set_sort_indicator(TriState eState,int nColumn=-1)334     void set_sort_indicator(TriState eState, int nColumn = -1)
335     {
336         m_xControl->set_sort_indicator(eState, nColumn);
337     }
get_sort_indicator(int nColumn=-1)338     TriState get_sort_indicator(int nColumn = -1)
339     {
340         return m_xControl->get_sort_indicator(nColumn);
341     }
342 
get_sort_column() const343     int get_sort_column() const { return m_xControl->get_sort_column(); }
set_sort_column(int nColumn)344     void set_sort_column(int nColumn) { m_xControl->set_sort_column(nColumn); }
345 
set_sort_func(const std::function<int (const weld::TreeIter &,const weld::TreeIter &)> & func)346     void set_sort_func(const std::function<int(const weld::TreeIter&, const weld::TreeIter&)>& func)
347     {
348         m_xControl->set_sort_func(func);
349     }
350 
351     void            RemoveEntry(const weld::TreeIter& rIter);
352     void            RemoveEntry(const ScriptDocument&);
353 
354     OUString        GetRootEntryName(const ScriptDocument& rDocument, LibraryLocation eLocation) const;
355     static OUString GetRootEntryBitmaps(const ScriptDocument& rDocument);
356 
357     void            SetCurrentEntry (EntryDescriptor const &);
358 
get_widget()359     weld::TreeView& get_widget() { return *m_xControl; }
360 
361 private:
362     LibraryType     GetLibraryType() const;
363 };
364 
365 } // namespace basctl
366 
367 #endif // INCLUDED_BASCTL_SOURCE_INC_BASTYPE2_HXX
368 
369 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
370