annotate framework/MainWindowBase.h @ 562:3c846b06c518 3.0-integration

When returning the frame that we have filled to, avoid accidentally reducing the frame number (making it appear we are less filled than we really are) when we had intended to round it up to the full requested amount. Fixes some unexpected double-playback in non-looping play-selection mode.
author Chris Cannam
date Wed, 14 Dec 2016 11:55:47 +0000
parents 21e3aab6e3e7
children 07e111dd5902
rev   line source
Chris@45 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@45 2
Chris@45 3 /*
Chris@45 4 Sonic Visualiser
Chris@45 5 An audio file viewer and annotation editor.
Chris@45 6 Centre for Digital Music, Queen Mary, University of London.
Chris@45 7 This file copyright 2006-2007 Chris Cannam and QMUL.
Chris@45 8
Chris@45 9 This program is free software; you can redistribute it and/or
Chris@45 10 modify it under the terms of the GNU General Public License as
Chris@45 11 published by the Free Software Foundation; either version 2 of the
Chris@45 12 License, or (at your option) any later version. See the file
Chris@45 13 COPYING included with this distribution for more information.
Chris@45 14 */
Chris@45 15
Chris@45 16 #ifndef _MAIN_WINDOW_BASE_H_
Chris@45 17 #define _MAIN_WINDOW_BASE_H_
Chris@45 18
Chris@45 19 #include <QFrame>
Chris@45 20 #include <QString>
Chris@45 21 #include <QUrl>
Chris@45 22 #include <QMainWindow>
Chris@45 23 #include <QPointer>
Chris@113 24 #include <QThread>
Chris@45 25
Chris@45 26 #include "base/Command.h"
Chris@45 27 #include "view/ViewManager.h"
Chris@45 28 #include "base/PropertyContainer.h"
Chris@45 29 #include "base/RecentFiles.h"
Chris@161 30 #include "base/FrameTimer.h"
Chris@45 31 #include "layer/LayerFactory.h"
Chris@106 32 #include "transform/Transform.h"
Chris@46 33 #include "SVFileReader.h"
Chris@170 34 #include "data/fileio/FileFinder.h"
Chris@45 35 #include "data/fileio/FileSource.h"
Chris@113 36 #include "data/osc/OSCQueue.h"
Chris@45 37 #include <map>
Chris@45 38
Chris@45 39 class Document;
Chris@45 40 class PaneStack;
Chris@45 41 class Pane;
Chris@45 42 class View;
Chris@45 43 class Fader;
Chris@45 44 class Overview;
Chris@45 45 class Layer;
Chris@45 46 class WaveformLayer;
Chris@45 47 class WaveFileModel;
Chris@45 48 class AudioCallbackPlaySource;
Chris@475 49 class AudioRecordTarget;
Chris@45 50 class CommandHistory;
Chris@45 51 class QMenu;
Chris@45 52 class AudioDial;
Chris@45 53 class QLabel;
Chris@45 54 class QCheckBox;
Chris@45 55 class PreferencesDialog;
Chris@45 56 class QTreeView;
Chris@45 57 class QPushButton;
Chris@45 58 class OSCMessage;
Chris@157 59 class MIDIInput;
Chris@45 60 class KeyReference;
Chris@45 61 class Labeller;
Chris@123 62 class ModelDataTableDialog;
Chris@391 63 class QSignalMapper;
Chris@391 64 class QShortcut;
Chris@429 65 class AlignmentModel;
Chris@45 66
Chris@468 67 namespace breakfastquay {
Chris@551 68 class SystemPlaybackTarget;
Chris@551 69 class SystemAudioIO;
Chris@551 70 class ResamplerWrapper;
Chris@468 71 }
Chris@468 72
Chris@45 73 /**
Chris@45 74 * The base class for the SV main window. This includes everything to
Chris@45 75 * do with general document and pane stack management, but nothing
Chris@45 76 * that involves user interaction -- this doesn't create the widget or
Chris@45 77 * menu structures or editing tools, and if a function needs to open a
Chris@45 78 * dialog, it shouldn't be in here. This permits "variations on SV"
Chris@45 79 * to use different subclasses retaining the same general structure.
Chris@45 80 */
Chris@45 81
Chris@161 82 class MainWindowBase : public QMainWindow, public FrameTimer
Chris@45 83 {
Chris@45 84 Q_OBJECT
Chris@45 85
Chris@45 86 public:
Chris@475 87 enum SoundOption {
Chris@475 88 WithAudioOutput = 0x01,
Chris@475 89 WithAudioInput = 0x02,
Chris@475 90 WithMIDIInput = 0x04,
Chris@515 91 WithEverything = 0xff,
Chris@515 92 WithNothing = 0x00
Chris@475 93 };
Chris@475 94 typedef int SoundOptions;
Chris@475 95
Chris@475 96 MainWindowBase(SoundOptions options = WithEverything);
Chris@45 97 virtual ~MainWindowBase();
Chris@45 98
Chris@45 99 enum AudioFileOpenMode {
Chris@221 100 ReplaceSession,
Chris@45 101 ReplaceMainModel,
Chris@45 102 CreateAdditionalModel,
Chris@45 103 ReplaceCurrentPane,
Chris@45 104 AskUser
Chris@45 105 };
Chris@45 106
Chris@45 107 enum FileOpenStatus {
Chris@45 108 FileOpenSucceeded,
Chris@45 109 FileOpenFailed,
Chris@45 110 FileOpenCancelled,
Chris@45 111 FileOpenWrongMode // attempted to open layer when no main model present
Chris@45 112 };
Chris@45 113
Chris@483 114 enum AudioRecordMode {
Chris@483 115 RecordReplaceSession,
Chris@483 116 RecordCreateAdditionalModel
Chris@483 117 };
Chris@483 118
Chris@45 119 virtual FileOpenStatus open(FileSource source, AudioFileOpenMode = AskUser);
Chris@373 120 virtual FileOpenStatus openPath(QString fileOrUrl, AudioFileOpenMode = AskUser);
dan@210 121 virtual FileOpenStatus openAudio(FileSource source, AudioFileOpenMode = AskUser, QString templateName = "");
Chris@45 122 virtual FileOpenStatus openPlaylist(FileSource source, AudioFileOpenMode = AskUser);
Chris@45 123 virtual FileOpenStatus openLayer(FileSource source);
Chris@45 124 virtual FileOpenStatus openImage(FileSource source);
Chris@45 125
Chris@427 126 virtual FileOpenStatus openDirOfAudio(QString dirPath);
Chris@427 127
Chris@45 128 virtual FileOpenStatus openSession(FileSource source);
Chris@373 129 virtual FileOpenStatus openSessionPath(QString fileOrUrl);
Chris@230 130 virtual FileOpenStatus openSessionTemplate(QString templateName);
Chris@227 131 virtual FileOpenStatus openSessionTemplate(FileSource source);
Chris@45 132
Chris@45 133 virtual bool saveSessionFile(QString path);
Chris@224 134 virtual bool saveSessionTemplate(QString path);
Chris@45 135
Chris@161 136 /// Implementation of FrameTimer interface method
Chris@435 137 virtual sv_frame_t getFrame() const;
Chris@161 138
Chris@357 139 void setDefaultFfwdRwdStep(RealTime step) {
Chris@357 140 m_defaultFfwdRwdStep = step;
Chris@357 141 }
Chris@357 142
Chris@483 143 void setAudioRecordMode(AudioRecordMode mode) {
Chris@483 144 m_audioRecordMode = mode;
Chris@483 145 }
Chris@483 146
Chris@45 147 signals:
Chris@45 148 // Used to toggle the availability of menu actions
Chris@45 149 void canAddPane(bool);
Chris@45 150 void canDeleteCurrentPane(bool);
Chris@45 151 void canAddLayer(bool);
Chris@45 152 void canImportMoreAudio(bool);
Chris@259 153 void canReplaceMainAudio(bool);
Chris@45 154 void canImportLayer(bool);
Chris@289 155 void canChangeSessionTemplate(bool);
Chris@45 156 void canExportAudio(bool);
Chris@45 157 void canExportLayer(bool);
Chris@45 158 void canExportImage(bool);
Chris@45 159 void canRenameLayer(bool);
Chris@45 160 void canEditLayer(bool);
Chris@146 161 void canEditLayerTabular(bool);
Chris@45 162 void canMeasureLayer(bool);
Chris@45 163 void canSelect(bool);
Chris@45 164 void canClearSelection(bool);
Chris@45 165 void canEditSelection(bool);
Chris@45 166 void canDeleteSelection(bool);
Chris@45 167 void canPaste(bool);
Chris@45 168 void canInsertInstant(bool);
Chris@45 169 void canInsertInstantsAtBoundaries(bool);
Chris@184 170 void canInsertItemAtSelection(bool);
Chris@45 171 void canRenumberInstants(bool);
Chris@537 172 void canSubdivideInstants(bool);
Chris@538 173 void canWinnowInstants(bool);
Chris@45 174 void canDeleteCurrentLayer(bool);
Chris@45 175 void canZoom(bool);
Chris@45 176 void canScroll(bool);
Chris@45 177 void canPlay(bool);
Chris@475 178 void canRecord(bool);
Chris@45 179 void canFfwd(bool);
Chris@45 180 void canRewind(bool);
Chris@45 181 void canPlaySelection(bool);
Chris@45 182 void canSpeedUpPlayback(bool);
Chris@45 183 void canSlowDownPlayback(bool);
Chris@45 184 void canChangePlaybackSpeed(bool);
Chris@73 185 void canSelectPreviousPane(bool);
Chris@73 186 void canSelectNextPane(bool);
Chris@73 187 void canSelectPreviousLayer(bool);
Chris@73 188 void canSelectNextLayer(bool);
Chris@45 189 void canSave(bool);
Chris@359 190 void canSaveAs(bool);
Chris@104 191 void hideSplash();
Chris@452 192 void hideSplash(QWidget *);
Chris@342 193 void sessionLoaded();
Chris@342 194 void audioFileLoaded();
Chris@160 195 void replacedDocument();
Chris@164 196 void activity(QString);
Chris@45 197
Chris@45 198 public slots:
Chris@45 199 virtual void preferenceChanged(PropertyContainer::PropertyName);
Chris@168 200 virtual void resizeConstrained(QSize);
Chris@556 201 virtual void recreateAudioIO();
Chris@45 202
Chris@45 203 protected slots:
Chris@45 204 virtual void zoomIn();
Chris@45 205 virtual void zoomOut();
Chris@45 206 virtual void zoomToFit();
Chris@45 207 virtual void zoomDefault();
Chris@45 208 virtual void scrollLeft();
Chris@45 209 virtual void scrollRight();
Chris@45 210 virtual void jumpLeft();
Chris@45 211 virtual void jumpRight();
Chris@162 212 virtual void peekLeft();
Chris@162 213 virtual void peekRight();
Chris@45 214
Chris@45 215 virtual void showNoOverlays();
Chris@45 216 virtual void showMinimalOverlays();
Chris@45 217 virtual void showAllOverlays();
Chris@45 218
Chris@211 219 virtual void toggleTimeRulers();
Chris@45 220 virtual void toggleZoomWheels();
Chris@45 221 virtual void togglePropertyBoxes();
Chris@45 222 virtual void toggleStatusBar();
Chris@256 223 virtual void toggleCentreLine();
Chris@45 224
Chris@45 225 virtual void play();
Chris@45 226 virtual void ffwd();
Chris@45 227 virtual void ffwdEnd();
Chris@45 228 virtual void rewind();
Chris@45 229 virtual void rewindStart();
Chris@477 230 virtual void record();
Chris@45 231 virtual void stop();
Chris@45 232
Chris@166 233 virtual void ffwdSimilar();
Chris@166 234 virtual void rewindSimilar();
Chris@166 235
Chris@45 236 virtual void deleteCurrentPane();
Chris@45 237 virtual void deleteCurrentLayer();
Chris@123 238 virtual void editCurrentLayer();
Chris@45 239
Chris@73 240 virtual void previousPane();
Chris@73 241 virtual void nextPane();
Chris@73 242 virtual void previousLayer();
Chris@73 243 virtual void nextLayer();
Chris@73 244
Chris@45 245 virtual void playLoopToggled();
Chris@45 246 virtual void playSelectionToggled();
Chris@45 247 virtual void playSoloToggled();
Chris@45 248
Chris@436 249 virtual void sampleRateMismatch(sv_samplerate_t, sv_samplerate_t, bool) = 0;
Chris@45 250 virtual void audioOverloadPluginDisabled() = 0;
Chris@130 251 virtual void audioTimeStretchMultiChannelDisabled() = 0;
Chris@45 252
Chris@435 253 virtual void playbackFrameChanged(sv_frame_t);
Chris@435 254 virtual void globalCentreFrameChanged(sv_frame_t);
Chris@435 255 virtual void viewCentreFrameChanged(View *, sv_frame_t);
Chris@366 256 virtual void viewZoomLevelChanged(View *, int, bool);
Chris@45 257 virtual void outputLevelsChanged(float, float) = 0;
Chris@485 258 virtual void recordDurationChanged(sv_frame_t, sv_samplerate_t);
Chris@45 259
Chris@45 260 virtual void currentPaneChanged(Pane *);
Chris@45 261 virtual void currentLayerChanged(Pane *, Layer *);
Chris@45 262
Chris@45 263 virtual void selectAll();
Chris@45 264 virtual void selectToStart();
Chris@45 265 virtual void selectToEnd();
Chris@45 266 virtual void selectVisible();
Chris@45 267 virtual void clearSelection();
Chris@45 268
Chris@45 269 virtual void cut();
Chris@45 270 virtual void copy();
Chris@45 271 virtual void paste();
Chris@215 272 virtual void pasteAtPlaybackPosition();
Chris@435 273 virtual void pasteRelative(sv_frame_t offset);
Chris@45 274 virtual void deleteSelected();
Chris@45 275
Chris@45 276 virtual void insertInstant();
Chris@435 277 virtual void insertInstantAt(sv_frame_t);
Chris@45 278 virtual void insertInstantsAtBoundaries();
Chris@184 279 virtual void insertItemAtSelection();
Chris@435 280 virtual void insertItemAt(sv_frame_t, sv_frame_t);
Chris@45 281 virtual void renumberInstants();
Chris@537 282 virtual void subdivideInstantsBy(int);
Chris@538 283 virtual void winnowInstantsBy(int);
Chris@45 284
Chris@45 285 virtual void documentModified();
Chris@45 286 virtual void documentRestored();
Chris@45 287
Chris@45 288 virtual void layerAdded(Layer *);
Chris@45 289 virtual void layerRemoved(Layer *);
Chris@45 290 virtual void layerAboutToBeDeleted(Layer *);
Chris@45 291 virtual void layerInAView(Layer *, bool);
Chris@45 292
Chris@45 293 virtual void mainModelChanged(WaveFileModel *);
Chris@45 294 virtual void modelAdded(Model *);
Chris@45 295 virtual void modelAboutToBeDeleted(Model *);
Chris@45 296
Chris@45 297 virtual void updateMenuStates();
Chris@45 298 virtual void updateDescriptionLabel() = 0;
Chris@45 299
Chris@78 300 virtual void modelGenerationFailed(QString, QString) = 0;
Chris@78 301 virtual void modelGenerationWarning(QString, QString) = 0;
Chris@78 302 virtual void modelRegenerationFailed(QString, QString, QString) = 0;
Chris@78 303 virtual void modelRegenerationWarning(QString, QString, QString) = 0;
Chris@429 304
Chris@429 305 virtual void alignmentComplete(AlignmentModel *);
Chris@420 306 virtual void alignmentFailed(QString) = 0;
Chris@45 307
Chris@45 308 virtual void rightButtonMenuRequested(Pane *, QPoint point) = 0;
Chris@45 309
Chris@45 310 virtual void paneAdded(Pane *) = 0;
Chris@45 311 virtual void paneHidden(Pane *) = 0;
Chris@45 312 virtual void paneAboutToBeDeleted(Pane *) = 0;
Chris@45 313 virtual void paneDropAccepted(Pane *, QStringList) = 0;
Chris@45 314 virtual void paneDropAccepted(Pane *, QString) = 0;
Chris@55 315 virtual void paneDeleteButtonClicked(Pane *);
Chris@45 316
Chris@113 317 virtual void oscReady();
Chris@45 318 virtual void pollOSC();
Chris@45 319 virtual void handleOSCMessage(const OSCMessage &) = 0;
Chris@45 320
Chris@45 321 virtual void contextHelpChanged(const QString &);
Chris@45 322 virtual void inProgressSelectionChanged();
Chris@45 323
Chris@141 324 virtual FileOpenStatus openSessionFromRDF(FileSource source);
Chris@145 325 virtual FileOpenStatus openLayersFromRDF(FileSource source);
Chris@141 326
Chris@45 327 virtual void closeSession() = 0;
Chris@45 328
Chris@452 329 virtual void emitHideSplash();
Chris@452 330
Chris@180 331 virtual void newerVersionAvailable(QString) { }
Chris@180 332
Chris@354 333 virtual void menuActionMapperInvoked(QObject *);
Chris@354 334
Chris@45 335 protected:
Chris@45 336 QString m_sessionFile;
Chris@45 337 QString m_audioFile;
Chris@45 338 Document *m_document;
Chris@45 339
Chris@45 340 PaneStack *m_paneStack;
Chris@45 341 ViewManager *m_viewManager;
Chris@45 342 Layer *m_timeRulerLayer;
Chris@45 343
Chris@475 344 SoundOptions m_soundOptions;
Chris@475 345
Chris@45 346 AudioCallbackPlaySource *m_playSource;
Chris@475 347 AudioRecordTarget *m_recordTarget;
Chris@551 348 breakfastquay::ResamplerWrapper *m_resamplerWrapper;
Chris@475 349 breakfastquay::SystemPlaybackTarget *m_playTarget; // only one of this...
Chris@475 350 breakfastquay::SystemAudioIO *m_audioIO; // ... and this exists
Chris@45 351
Chris@113 352 class OSCQueueStarter : public QThread
Chris@113 353 {
Chris@113 354 public:
Chris@113 355 OSCQueueStarter(MainWindowBase *mwb) : QThread(mwb), m_mwb(mwb) { }
Chris@113 356 virtual void run() {
Chris@113 357 OSCQueue *queue = new OSCQueue(); // can take a long time
Chris@113 358 m_mwb->m_oscQueue = queue;
Chris@113 359 }
Chris@113 360 private:
Chris@113 361 MainWindowBase *m_mwb;
Chris@113 362 };
Chris@113 363
Chris@45 364 OSCQueue *m_oscQueue;
Chris@113 365 OSCQueueStarter *m_oscQueueStarter;
Chris@304 366 void startOSCQueue();
Chris@45 367
Chris@157 368 MIDIInput *m_midiInput;
Chris@157 369
Chris@45 370 RecentFiles m_recentFiles;
Chris@54 371 RecentFiles m_recentTransforms;
Chris@45 372
Chris@45 373 bool m_documentModified;
Chris@45 374 bool m_openingAudioFile;
Chris@45 375 bool m_abandoning;
Chris@45 376
Chris@45 377 Labeller *m_labeller;
Chris@45 378
Chris@45 379 int m_lastPlayStatusSec;
Chris@45 380 mutable QString m_myStatusMessage;
Chris@45 381
Chris@45 382 bool m_initialDarkBackground;
Chris@45 383
Chris@357 384 RealTime m_defaultFfwdRwdStep;
Chris@357 385
Chris@483 386 AudioRecordMode m_audioRecordMode;
Chris@483 387
Chris@378 388 mutable QLabel *m_statusLabel;
Chris@378 389 QLabel *getStatusLabel() const;
Chris@378 390
Chris@45 391 WaveFileModel *getMainModel();
Chris@45 392 const WaveFileModel *getMainModel() const;
Chris@45 393 void createDocument();
Chris@45 394
Chris@45 395 Pane *addPaneToStack();
Chris@45 396 Layer *getSnapLayer() const;
Chris@45 397
Chris@126 398 typedef std::map<Layer *, QPointer<ModelDataTableDialog> > LayerDataDialogMap;
Chris@126 399 typedef std::set<QPointer<ModelDataTableDialog> > DataDialogSet;
Chris@123 400 typedef std::map<View *, DataDialogSet> ViewDataDialogMap;
Chris@123 401
Chris@123 402 LayerDataDialogMap m_layerDataDialogMap;
Chris@123 403 ViewDataDialogMap m_viewDataDialogMap;
Chris@123 404
Chris@128 405 void removeLayerEditDialog(Layer *);
Chris@128 406
Chris@45 407 class PaneCallback : public SVFileReaderPaneCallback
Chris@45 408 {
Chris@45 409 public:
Chris@45 410 PaneCallback(MainWindowBase *mw) : m_mw(mw) { }
Chris@45 411 virtual Pane *addPane() { return m_mw->addPaneToStack(); }
Chris@45 412 virtual void setWindowSize(int width, int height) {
Chris@168 413 m_mw->resizeConstrained(QSize(width, height));
Chris@45 414 }
Chris@435 415 virtual void addSelection(sv_frame_t start, sv_frame_t end) {
Chris@344 416 m_mw->m_viewManager->addSelectionQuietly(Selection(start, end));
Chris@45 417 }
Chris@45 418 protected:
Chris@45 419 MainWindowBase *m_mw;
Chris@45 420 };
Chris@45 421
Chris@45 422 class AddPaneCommand : public Command
Chris@45 423 {
Chris@45 424 public:
Chris@45 425 AddPaneCommand(MainWindowBase *mw);
Chris@45 426 virtual ~AddPaneCommand();
Chris@45 427
Chris@45 428 virtual void execute();
Chris@45 429 virtual void unexecute();
Chris@45 430 virtual QString getName() const;
Chris@45 431
Chris@45 432 Pane *getPane() { return m_pane; }
Chris@45 433
Chris@45 434 protected:
Chris@45 435 MainWindowBase *m_mw;
Chris@45 436 Pane *m_pane; // Main window owns this, but I determine its lifespan
Chris@45 437 Pane *m_prevCurrentPane; // I don't own this
Chris@45 438 bool m_added;
Chris@45 439 };
Chris@45 440
Chris@45 441 class RemovePaneCommand : public Command
Chris@45 442 {
Chris@45 443 public:
Chris@45 444 RemovePaneCommand(MainWindowBase *mw, Pane *pane);
Chris@45 445 virtual ~RemovePaneCommand();
Chris@45 446
Chris@45 447 virtual void execute();
Chris@45 448 virtual void unexecute();
Chris@45 449 virtual QString getName() const;
Chris@45 450
Chris@45 451 protected:
Chris@45 452 MainWindowBase *m_mw;
Chris@45 453 Pane *m_pane; // Main window owns this, but I determine its lifespan
Chris@45 454 Pane *m_prevCurrentPane; // I don't own this
Chris@45 455 bool m_added;
Chris@45 456 };
Chris@45 457
Chris@45 458 virtual bool checkSaveModified() = 0;
Chris@45 459
Chris@45 460 virtual QString getOpenFileName(FileFinder::FileType type);
Chris@45 461 virtual QString getSaveFileName(FileFinder::FileType type);
Chris@45 462 virtual void registerLastOpenedFilePath(FileFinder::FileType type, QString path);
Chris@45 463
Chris@222 464 virtual QString getDefaultSessionTemplate() const;
Chris@251 465 virtual void setDefaultSessionTemplate(QString);
Chris@222 466
Chris@475 467 virtual void createAudioIO();
Chris@556 468 virtual void deleteAudioIO();
Chris@556 469
Chris@45 470 virtual void openHelpUrl(QString url);
Chris@483 471 virtual void openLocalFolder(QString path);
Chris@45 472
Chris@45 473 virtual void setupMenus() = 0;
Chris@45 474 virtual void updateVisibleRangeDisplay(Pane *p) const = 0;
Chris@187 475 virtual void updatePositionStatusDisplays() const = 0;
Chris@45 476
Chris@354 477 // Call this after setting up the menu bar, to fix up single-key
Chris@426 478 // shortcuts on OS/X and do any other platform-specific tidying
Chris@354 479 virtual void finaliseMenus();
Chris@354 480 virtual void finaliseMenu(QMenu *);
Chris@394 481
Chris@426 482 // Call before finaliseMenus if you wish to have a say in this question
Chris@426 483 void setIconsVisibleInMenus(bool visible) { m_iconsVisibleInMenus = visible; }
Chris@426 484 bool m_iconsVisibleInMenus;
Chris@426 485
Chris@394 486 // Only used on OS/X to work around a Qt/Cocoa bug, see finaliseMenus
Chris@391 487 QSignalMapper *m_menuShortcutMapper;
Chris@391 488 QList<QShortcut *> m_appShortcuts;
Chris@354 489
Chris@147 490 virtual bool shouldCreateNewSessionForRDFAudio(bool *) { return true; }
Chris@145 491
Chris@128 492 virtual void connectLayerEditDialog(ModelDataTableDialog *dialog);
Chris@128 493
Chris@226 494 virtual void toXml(QTextStream &stream, bool asTemplate);
Chris@45 495 };
Chris@45 496
Chris@45 497
Chris@45 498 #endif