summaryrefslogtreecommitdiffstats
path: root/kexi/core/kexiviewbase.h
blob: 8102a9c41290dfba58031ee2c25f69e1c4845d53 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
/* This file is part of the KDE project
   Copyright (C) 2004 Jaroslaw Staniek <[email protected]>

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public
   License as published by the Free Software Foundation; either
   version 2 of the License, or (at your option) any later version.

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public License
   along with this library; see the file COPYING.LIB.  If not, write to
   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
*/

#ifndef KEXIVIEWBASE_H
#define KEXIVIEWBASE_H

#include <tqwidget.h>

#include "kexiactionproxy.h"

class KexiMainWindow;
class KexiDialogBase;

namespace KoProperty {
	class Set;
}

namespace KexiDB {
	class SchemaData;
}

//! Base class for single view embeddable of in KexiDialogBase.
/*! This class automatically works as a proxy for shared (application-wide) actions.
 KexiViewBase has 'dirty' flag to indicate that view's data has changed.
 This flag's state is reused by KexiDialogBase object that contain the view.
 KexiViewBase objects can be also nested, using addChildView(): any actions and 'dirty' flag
 are transmited to parent view in this case.

 KexiViewBase objects are usually allocated within KexiDialogBase objects by implementing
 KexiPart::createView() method. See query or table part code for examples.

 KexiViewBase object can be also allocated without attaching it KexiDialogBase,
 especially withinn dock window. see KexiMainWindowImpl::initNavigator() to see example
 how KexiBrowser does this.
*/
class KEXICORE_EXPORT KexiViewBase : public TQWidget, public KexiActionProxy
{
	TQ_OBJECT
  

	public:
		KexiViewBase(KexiMainWindow *mainWin, TQWidget *parent, const char *name = 0);
		virtual ~KexiViewBase();

		//! \return kexi main window that contain this view
		inline KexiMainWindow *mainWin() const { return m_mainWin; }

		//! \return parent KexiDialogBase that contains this view, or 0 if no dialog contain this view
		KexiDialogBase* parentDialog() const { return m_dialog; }

		/*! Added for convenience.
		 \return KexiPart object that was used to create this view (with a dialog)
		 or 0 if this view is not created using KexiPart. \sa parentDialog() */
		KexiPart::Part* part() const;

		/*! \return preferred size hint, that can be used to resize the view.
		 It is computed using maximum of (a) \a otherSize and (b) current KMDI dock area's size,
		 so the view won't exceed this maximum size. The method is used e.g. in KexiDialogBase::sizeHint().
		 If you reimplement this method, do not forget to return value of
		 yoursize.boundedTo( KexiViewBase::preferredSizeHint(otherSize) ). */
		virtual TQSize preferredSizeHint(const TQSize& otherSize);

		virtual bool eventFilter( TQObject *o, TQEvent *e );

		void addChildView( KexiViewBase* childView );

		/*! True if contents (data) of the view is dirty and need to be saved
		 This may or not be used, depending if changes in the dialog
		 are saved immediately (e.g. like in datatableview) or saved by hand (by user)
		 (e.g. like in alter-table dialog).
		 "Dirty" flag is reused by KexiDialogBase::dirty().
		 Default implementation just uses internal m_dirty flag, that is false by default.
		 Reimplement this if you e.g. want reuse other "dirty"
		 flag from internal structures that may be changed. */
		virtual bool dirty() const { return m_dirty; }

		/*! \return the view mode for this view. */
		int viewMode() const { return m_viewMode; }

		/*! Reimpelmented from KexiActionProxy.
		 \return shared action with name \a action_name for this view.
		 If there's no such action declared in Kexi Part (part()),
		 global shared action is returned (if exists). */
		virtual TDEAction* sharedAction( const char *action_name );

		/*! Enables or disables shared action declared in Kexi Part (part()).
		 If there's no such action, global shared action is enabled or disabled (if exists). */
		virtual void setAvailable(const char* action_name, bool set);

	public slots:
		virtual void setFocus();

		/*! Call this in your view's implementation whenever current property set
		 (returned by propertySet()) is switched to other,
		 so property editor contents need to be completely replaced. */
		virtual void propertySetSwitched();

		/*! Sets dirty flag on or off. It the flag changes,
		 dirty(bool) signal is emitted by parent dialog (KexiDialog),
		 to inform the world about that. If this view has a parent view, setDirty()
		 is called also on parent view.
		 Always use this function to update 'dirty' flag information. */
		void setDirty(bool set);

		/*! Equal to setDirty(true). */
		void setDirty() { setDirty(true); }

	signals:
		//! emitted when the view is about to close
		void closing(bool& cancel);

		void focus(bool in);

	protected:
		/*! called by KexiDialogBase::switchToViewMode() right before dialog is switched to new mode
		 By default does nothing. Reimplement this if you need to do something
		 before switching to this view.
		 \return true if you accept or false if a error occupied and view shouldn't change
		 If there is no error but switching should be just cancelled
		 (probably after showing some info messages), you need to return cancelled.
		 Set \a dontStore to true (it's false by default) if you want to avoid data storing
		 by storeData() or storeNewData(). */
		virtual tristate beforeSwitchTo(int mode, bool &dontStore);

		/*! called by KexiDialogBase::switchToViewMode() right after dialog is switched to new mode
		 By default does nothing. Reimplement this if you need to do something
		 after switching to this view.
		 \return true if you accept or false if a error occupied and view shouldn't change
		 If there is no error but switching should be just cancelled
		 (probably after showing some info messages), you need to return cancelled. */
		virtual tristate afterSwitchFrom(int mode);

		virtual void closeEvent( TQCloseEvent * e );

		/*! \return a property set for this view. For reimplementation. By default returns NULL. */
		virtual KoProperty::Set *propertySet();

		/*! Call this in your view's implementation whenever current property set
		 is changed that few properties are now visible and/or few other are invisible,
		 so property editor operating on this property set should be completely reloaded.
		 If \a preservePrevSelection is true and there was a property set
		 assigned before call, previously selected item will be preselected
		 in the editor (if found). */
		void propertySetReloaded(bool preservePrevSelection = false, const TQCString& propertyToSelect = TQCString());

		/*! Tells this dialog to create and store data of the new object
		 pointed by \a sdata on the backend.
		 Called by KexiDialogBase::storeNewData().
		 Default implementation:
		 - makes a deep copy of \a sdata
		 - stores object schema data \a sdata in 'kexi__objects' internal table
		   using Connection::storeObjectSchemaData().
		 Reimpelment this for your needs.
		 Requirements:
		 - deep copy of \a sdata should be made
		 - schema data should be created at the backend
		   (by calling KexiViewBase::storeNewData(const KexiDB::SchemaData& sdata)),
		   or using Connection::storeObjectSchemaData() or more specialized
		   method. For example, KexiAlterTableDialog
		   uses Connection::createTable(TableSchema) for this
		   (tableschema is SchemaData subclass) to store more information than
		   just a schem adata. You should use such subclasses if needed.
		 Should return newly created schema data object on success.
		 In this case, do not store schema object yourself (make deep copy if needed). */
		virtual KexiDB::SchemaData* storeNewData(const KexiDB::SchemaData& sdata, bool &cancel);

		/*! Loads large string data \a dataString block (e.g. xml form's representation),
		 indexed with optional \a dataID, from the database backend. 
		 If \a canBeEmpty is true and there is no data block for dataID, true is returned
		 and \a dataString is set to null string. The default is false.
		 \return true on success
		 \sa storeDataBlock(). */
		bool loadDataBlock( TQString &dataString, const TQString& dataID = TQString(), bool canBeEmpty = false );

		/*! Tells this view to store data changes on the backend.
		 Called by KexiDialogBase::storeData().
		 Default implementation:
		 - makes a deep copy of \a sdata
		 - stores object schema data \a sdata in 'kexi__objects' internal table
		   using Connection::storeObjectSchemaData().
		 If \a dontAsk is true, no question dialog will 
		 be shown to the user. The default is false.

		 Reimpelment this for your needs. Should return true on success 
		 or cancelled when the task should be cancelled.
		 \sa storeNewData() */
		virtual tristate storeData(bool dontAsk = false);

		/*! Stores (potentially large) string data \a dataString, block (e.g. xml form's representation),
		 at the database backend. Block will be stored in "kexi__objectdata" table pointed by
		 this object's id and an optional \a dataID identifier.

		 If dialog's id is not available (KexiDialogBase::id()),
		 then ID that was just created in storeNewData() is used
		 (see description of m_newlyAssignedID member).
		 If there is already such record in the table, it's simply overwritten.
		 \return true on success
		*/
		bool storeDataBlock( const TQString &dataString, const TQString &dataID = TQString() );

		/*! Removes (potentially large) string data (e.g. xml form's representation),
		 pointed by optional \a dataID, from the database backend.
		 \return true on success. Does not fail if the block doe not exists.
		 Note that if \a dataID is not specified, all data blocks for this view will be removed.
		 \sa storeDataBlock(). */
		bool removeDataBlock( const TQString& dataID = TQString());

		void setViewWidget(TQWidget* w, bool focusProxy = false);

		/*! Updates actions (e.g. availability). Reimplement it, if needed (you must
		 call superclass impelmentation at the end!).
		 This implementation does nothing for this view but calls updateActions()
		 for every child-view of this view.
		 called by KexiDialogBase on dialog's activation (\a activated is true)
		 or deactivation. */
		virtual void updateActions(bool activated);

		virtual void setFocusInternal() { TQWidget::setFocus(); }

		/*! Allows to react on parent dialog's detaching (only for KMDI's ChildFrame mode)
		 - it is called by KexiDialogBase::youAreDetached().
		 Default implementation does nothing.
		 Implement it if you want to perform some appropriate actions. */
		virtual void parentDialogDetached() {};

		/*! Allows to react on parent dialog's attaching (only for KMDI's ChildFrame mode)
		 - it is called by KexiDialogBase::youAreAttached().
		 Default implementation does nothing.
		 Implement it if you want to perform some appropriate actions. */
		virtual void parentDialogAttached() {};

		TQString m_defaultIconName;

		KexiMainWindow *m_mainWin;

		KexiDialogBase *m_dialog;

		TQWidget *m_viewWidget;

		KexiViewBase *m_parentView;

		TQGuardedPtr<TQWidget> m_lastFocusedChildBeforeFocusOut;

	private:
		/*! Member set to newly assigned object's ID in storeNewData()
		 and used in storeDataBlock(). This is needed because usually,
		 storeDataBlock() can be called from storeNewData() and in this case
		 dialog has not yet assigned valid identifier (it has just negative temp. number).
		 \sa KexiDialogBase::id()
		 */
		int m_newlyAssignedID;

		/*! Mode for this view. Initialized by KexiDialogBase::switchToViewMode().
		 Can be useful when single class is used for more than one view (e.g. KexiDBForm). */
		int m_viewMode;

		TQPtrList<KexiViewBase> m_children;

		bool m_dirty : 1;

	friend class KexiDialogBase;
};

#endif