00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef GNOMEMM_APP_HELPER_H
00022 #define GNOMEMM_APP_HELPER_H
00023
00024 #include <new>
00025 #include <gtkmm/menushell.h>
00026 #include <gtkmm/toolbar.h>
00027 #include <gtkmm/accelgroup.h>
00028 #include <libgnomeuimm/ui-items-icon.h>
00029 #include <libgnomeui/gnome-app.h>
00030 #include <libgnomeui/gnome-app-helper.h>
00031 #include <vector>
00032
00033 namespace Gnome
00034 {
00035
00036 namespace UI
00037 {
00038
00039 namespace Items
00040 {
00041
00042 class Icon;
00043
00044
00045
00046
00047
00048 template<class T_Info>
00049 class Array;
00050
00051 class InfoData;
00052
00053
00054
00055
00056 class Info : public GnomeUIInfo
00057 {
00058 friend class InfoData;
00059 friend class Array<Info>;
00060
00061
00062 void* operator new(size_t s);
00063 public:
00064 void* operator new(size_t s, void* v) {return ::operator new(s, v);}
00065
00066 Info();
00067 Info(const Info& src);
00068 ~Info();
00069 Info& operator=(const Info& src);
00070
00071 Gtk::Widget* get_widget();
00072 const Gtk::Widget* get_widget() const;
00073
00074 enum Type
00075 {
00076 END = GNOME_APP_UI_ENDOFINFO,
00077 ITEM = GNOME_APP_UI_ITEM,
00078 TOGGLEITEM = GNOME_APP_UI_TOGGLEITEM,
00079 RADIOITEMS = GNOME_APP_UI_RADIOITEMS,
00080 SUBTREE = GNOME_APP_UI_SUBTREE,
00081 SEPARATOR = GNOME_APP_UI_SEPARATOR,
00082 HELP = GNOME_APP_UI_HELP,
00083 BUILDER = GNOME_APP_UI_BUILDER_DATA,
00084 CONFIGURABLE = GNOME_APP_UI_ITEM_CONFIGURABLE,
00085 SUBTREE_STOCK = GNOME_APP_UI_SUBTREE_STOCK
00086 };
00087
00088 Type type() const;
00089
00090 const gchar* debug_get_icon_info() const;
00091
00092 typedef Gtk::Menu_Helpers::AccelKey AccelKey;
00093 void set_accel(AccelKey ak = AccelKey());
00094
00095 typedef SigC::Slot0<void> Callback;
00096 typedef SigC::Slot1<void, Gtk::Widget*> CallbackWithWidget;
00097
00098 protected:
00099 void init(Type type_);
00100 void init_cb(Type type_, const Icon& icon,
00101 const Glib::ustring& label, const Callback& cb,
00102 const Glib::ustring& tooltip);
00103 void init_cbw(Type type_, const Icon& icon,
00104 const Glib::ustring& label, const CallbackWithWidget& cb,
00105 const Glib::ustring& tooltip);
00106 void init_sub(Type type_, const Icon& icon,
00107 const Glib::ustring& label, const Array<Info>& sub,
00108 const Glib::ustring& tooltip);
00109 InfoData* init_common(Type type_, const Icon& icon_,
00110 const Glib::ustring& label_, const Glib::ustring& hint_);
00111
00112 InfoData* get_data_();
00113 const InfoData* get_data_() const;
00114
00115 void set_data_(InfoData* infodata);
00116 };
00117
00118
00119
00120
00121
00122
00123
00124 class SubTree : public Info
00125 {
00126 protected:
00127 SubTree();
00128 public:
00129 SubTree(const Glib::ustring& label, const Array<Info>& uitree,
00130 const Glib::ustring& tip = Glib::ustring());
00131 SubTree(const Icon& icon, const Glib::ustring& label,
00132 const Array<Info>& uitree, const Glib::ustring& tip = Glib::ustring());
00133 ~SubTree();
00134
00135 Array<Info>& get_uitree();
00136 };
00137 typedef SubTree Menu;
00138
00139
00140
00141 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00142
00143 class Begin : public Info
00144 {
00145 public:
00146 Begin();
00147
00148 private:
00149 static GnomeUIBuilderData build_data_;
00150 };
00151
00152
00153 class End : public Info
00154 {
00155 public:
00156 End();
00157 };
00158 #endif
00159
00160 namespace Array_Helpers
00161 {
00162
00163 template<class T>
00164 struct Traits
00165 {
00166 typedef typename T::const_iterator iterator;
00167 static iterator begin(const T& t) {return t.begin();}
00168 static iterator end(const T& t) {return t.end();}
00169 };
00170
00171
00172 template<class T_Info>
00173 struct Traits<T_Info*>
00174 {
00175 typedef const T_Info* iterator;
00176 static iterator begin(const T_Info* t) {return t;}
00177 static iterator end( T_Info* t) {return t+64;}
00178 };
00179
00180 template<size_t N, class T_Info>
00181 struct Traits<T_Info[N]>
00182 {
00183 typedef const T_Info* iterator;
00184 static iterator begin(const T_Info* t) {return t;}
00185 static iterator end(const T_Info* t) {return &t[N];}
00186 };
00187
00188 }
00189
00190
00191
00192
00193 template<class T_Info>
00194 class Array
00195 {
00196
00197 Info* data_;
00198 Info* begin_;
00199 int size_;
00200
00201 template <class I> void create(I b, I e);
00202 public:
00203 typedef T_Info value_type;
00204 typedef T_Info& reference_type;
00205 typedef T_Info* iterator;
00206 typedef T_Info* const const_iterator;
00207 typedef T_Info* const pointer;
00208 typedef T_Info* const const_pointer;
00209 typedef size_t size_type;
00210 typedef ptrdiff_t difference_type;
00211
00212 Array& operator=(const Array& a)
00213 {
00214 if (this == &a)
00215 return *this;
00216
00217 delete [] data_;
00218 data_ = 0;
00219 size_ = 0;
00220
00221 create(a.begin(), a.end());
00222 return *this;
00223 }
00224
00225 Array()
00226 : data_(0), begin_(0), size_(0)
00227 { create((T_Info*)0, (T_Info*)0); }
00228
00229 Array(Array& a)
00230 : data_(0), begin_(0), size_(0)
00231 { create(a.begin(), a.end()); }
00232
00233 template <class T>
00234 Array(const T& t)
00235 : data_(0), begin_(0), size_(0)
00236 { create(Array_Helpers::Traits<T>::begin(t),
00237 Array_Helpers::Traits<T>::end(t));
00238 }
00239
00240 template <class I>
00241 Array(I b, I e)
00242 : data_(0), begin_(0), size_(0)
00243 { create(b, e); }
00244
00245 ~Array()
00246 {
00247 delete [] data_;
00248 data_ = 0;
00249 size_ = 0;
00250 }
00251
00252 size_t size() const { return size_; }
00253
00254 iterator begin() const
00255 { return static_cast<T_Info*>(begin_); }
00256
00257 iterator end() const
00258 { return static_cast<T_Info*>(begin_ + size_); }
00259
00260 reference_type operator[](size_t n) const
00261 { return static_cast<T_Info&>(begin_[n]); }
00262
00263
00264 GnomeUIInfo* gobj() const
00265 { return static_cast<GnomeUIInfo*>(data_); }
00266
00267 };
00268
00269
00270 template <class T_Info>
00271 template <class I>
00272 void
00273 Array<T_Info>::create(I b, I e)
00274 {
00275
00276
00277 if (b == e)
00278 {
00279 data_ = new End[1];
00280 return;
00281 }
00282
00283
00284 for (I b2 = b ; b2 != e; ++b2, ++size_)
00285 {
00286 if (b2->type() == Info::END)
00287 break;
00288 }
00289
00290
00291 if (b->type() != Info::BUILDER)
00292 {
00293 begin_ = data_ = new Info[size_+2];
00294 new (begin_) Begin();
00295 begin_++;
00296 }
00297 else
00298 begin_ = data_ = new Info[size_+1];
00299
00300
00301 for (int i = 0; b != e; ++b, ++i)
00302 {
00303 new (&begin_[i]) T_Info(*b);
00304 }
00305
00306 new (&begin_[size_]) End();
00307
00308
00309
00310 }
00311
00312
00313 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00314
00315
00316
00317
00318 class InfoData
00319 {
00320 public:
00321 InfoData();
00322 InfoData(const Glib::ustring& label, const Glib::ustring& hint, const Icon& icon = Icon());
00323
00324 private:
00325 InfoData(const InfoData&);
00326 protected:
00327 virtual ~InfoData();
00328
00329 public:
00330
00331 void ref();
00332 void unref();
00333
00334 virtual void connect(Info&);
00335
00336 typedef SigC::Slot0<void> Callback;
00337 typedef SigC::Slot1<void, Gtk::Widget*> CallbackWithWidget;
00338
00339 void set_callback(const Callback& callback);
00340 void set_callback(const CallbackWithWidget& callback);
00341 void set_subtree(const Array<Info>& subtree);
00342 Array<Info>& get_subtree();
00343
00344
00345 CallbackWithWidget callback_;
00346 Array<Info> subtree_;
00347 Glib::ustring label_;
00348 Glib::ustring hint_;
00349 Icon icon_;
00350
00351 private:
00352 int ref_count_;
00353 };
00354 #endif
00355
00356
00360 Items::Array<Info> fill (Gtk::MenuShell &menu_shell,
00361 const Items::Array<Info> &info,
00362 const Glib::RefPtr<Gtk::AccelGroup> &accel_group,
00363 bool uline_accels = true,
00364 int pos = 0);
00365
00366
00370 Items::Array<Info> fill (Gtk::Toolbar &toolbar,
00371 const Items::Array<Info> &info,
00372 const Glib::RefPtr<Gtk::AccelGroup> &accel_group);
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388 }
00389 }
00390 }
00391
00392 #endif //GNOMEMM_APP_HELPER_H