mirror of
https://github.com/cookiengineer/audacity
synced 2025-11-03 07:33:49 +01:00
Locate and position the current Audacity source code, and clear a variety of old junk out of the way into junk-branches
This commit is contained in:
576
src/Project.h
Normal file
576
src/Project.h
Normal file
@@ -0,0 +1,576 @@
|
||||
/**********************************************************************
|
||||
|
||||
Audacity: A Digital Audio Editor
|
||||
|
||||
Project.h
|
||||
|
||||
Dominic Mazzoni
|
||||
|
||||
In Audacity, the main window you work in is called a project.
|
||||
Projects can contain an arbitrary number of tracks of many
|
||||
different types, but if a project contains just one or two
|
||||
tracks then it can be saved in standard formats like WAV or AIFF.
|
||||
This window is the one that contains the menu bar (except on
|
||||
the Mac).
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef __AUDACITY_PROJECT__
|
||||
#define __AUDACITY_PROJECT__
|
||||
|
||||
#include "Audacity.h"
|
||||
|
||||
#include "DirManager.h"
|
||||
#include "UndoManager.h"
|
||||
#include "ViewInfo.h"
|
||||
#include "TrackPanel.h"
|
||||
#include "AudioIO.h"
|
||||
#include "commands/CommandManager.h"
|
||||
#include "effects/EffectManager.h"
|
||||
#include "xml/XMLTagHandler.h"
|
||||
#include "toolbars/SelectionBar.h"
|
||||
#include "FreqWindow.h"
|
||||
|
||||
#include <wx/defs.h>
|
||||
#include <wx/event.h>
|
||||
#include <wx/log.h>
|
||||
#include <wx/dragimag.h>
|
||||
#include <wx/generic/dragimgg.h>
|
||||
#include <wx/frame.h>
|
||||
#include <wx/intl.h>
|
||||
#include <wx/dcclient.h>
|
||||
|
||||
const int AudacityProjectTimerID = 5200;
|
||||
|
||||
class wxWindow;
|
||||
class wxDialog;
|
||||
class wxBoxSizer;
|
||||
class wxScrollEvent;
|
||||
class wxScrollBar;
|
||||
class wxPanel;
|
||||
|
||||
class ToolManager;
|
||||
class Toolbar;
|
||||
class ControlToolBar;
|
||||
class DeviceToolBar;
|
||||
class EditToolBar;
|
||||
class MeterToolBar;
|
||||
class MixerToolBar;
|
||||
class SelectionToolBar;
|
||||
class ToolsToolBar;
|
||||
class TranscriptionToolBar;
|
||||
|
||||
class TrackList;
|
||||
class Tags;
|
||||
class HistoryWindow;
|
||||
#ifdef EXPERIMENTAL_LYRICS_WINDOW
|
||||
class LyricsWindow;
|
||||
#endif
|
||||
#ifdef EXPERIMENTAL_MIXER_BOARD
|
||||
class MixerBoard;
|
||||
class MixerBoardFrame;
|
||||
#endif
|
||||
class Importer;
|
||||
class AdornedRulerPanel;
|
||||
|
||||
class AudacityProject;
|
||||
class RecordingRecoveryHandler;
|
||||
class ODLock;
|
||||
|
||||
AudacityProject *CreateNewAudacityProject();
|
||||
AUDACITY_DLL_API AudacityProject *GetActiveProject();
|
||||
void RedrawAllProjects();
|
||||
void RefreshCursorForAllProjects();
|
||||
AUDACITY_DLL_API void CloseAllProjects();
|
||||
|
||||
void GetDefaultWindowRect(wxRect *defRect);
|
||||
void GetNextWindowPlacement(wxRect *nextRect, bool *pMaximized, bool *pIconized);
|
||||
bool IsWindowAccessible(wxRect *requestedRect);
|
||||
|
||||
WX_DEFINE_ARRAY(AudacityProject *, AProjectArray);
|
||||
|
||||
extern AProjectArray gAudacityProjects;
|
||||
|
||||
|
||||
WX_DEFINE_ARRAY(wxMenu *, MenuArray);
|
||||
|
||||
enum PlayMode {
|
||||
normalPlay,
|
||||
oneSecondPlay,
|
||||
loopedPlay
|
||||
};
|
||||
|
||||
// XML handler for <import> tag
|
||||
class ImportXMLTagHandler : public XMLTagHandler
|
||||
{
|
||||
public:
|
||||
ImportXMLTagHandler(AudacityProject* pProject) { mProject = pProject; };
|
||||
|
||||
virtual bool HandleXMLTag(const wxChar *tag, const wxChar **attrs);
|
||||
virtual XMLTagHandler *HandleXMLChild(const wxChar *tag) { return NULL; };
|
||||
virtual void WriteXML(XMLWriter &xmlFile) { wxASSERT(false); } //vvv todo
|
||||
private:
|
||||
AudacityProject* mProject;
|
||||
};
|
||||
|
||||
class AUDACITY_DLL_API AudacityProject: public wxFrame,
|
||||
public TrackPanelListener,
|
||||
public SelectionBarListener,
|
||||
public XMLTagHandler,
|
||||
public AudioIOListener
|
||||
{
|
||||
public:
|
||||
|
||||
// Constructor and Destructor
|
||||
|
||||
AudacityProject(wxWindow * parent, wxWindowID id,
|
||||
const wxPoint & pos, const wxSize & size);
|
||||
|
||||
virtual ~ AudacityProject();
|
||||
|
||||
TrackList *GetTracks() { return mTracks; };
|
||||
UndoManager *GetUndoManager() { return &mUndoManager; }
|
||||
|
||||
sampleFormat GetDefaultFormat() { return mDefaultFormat; }
|
||||
|
||||
double GetRate() { return mRate; }
|
||||
double GetZoom() { return mViewInfo.zoom; }
|
||||
double GetSel0() { return mViewInfo.sel0; }
|
||||
double GetSel1() { return mViewInfo.sel1; }
|
||||
|
||||
Track *GetFirstVisible();
|
||||
void UpdateFirstVisible();
|
||||
|
||||
void GetPlayRegion(double* playRegionStart, double *playRegionEnd);
|
||||
bool IsPlayRegionLocked() { return mLockPlayRegion; }
|
||||
|
||||
void SetSel0(double); //Added by STM
|
||||
void SetSel1(double); //Added by STM
|
||||
|
||||
bool Clipboard() { return msClipLen > 0.0; }
|
||||
|
||||
wxString GetName();
|
||||
DirManager *GetDirManager();
|
||||
TrackFactory *GetTrackFactory();
|
||||
AdornedRulerPanel *GetRulerPanel();
|
||||
Tags *GetTags();
|
||||
int GetAudioIOToken();
|
||||
void SetAudioIOToken(int token);
|
||||
|
||||
bool IsActive();
|
||||
|
||||
// File I/O
|
||||
|
||||
/** @brief Show an open dialogue for opening audio files, and possibly other
|
||||
* sorts of files.
|
||||
*
|
||||
* The file type filter will automatically contain:
|
||||
* - "All files" with any extension or none,
|
||||
* - "All supported files" based on the file formats supported in this
|
||||
* build of Audacity,
|
||||
* - All of the individual formats specified by the importer plug-ins which
|
||||
* are built into this build of Audacity, each with the relevant file
|
||||
* extensions for that format.
|
||||
* The dialogue will start in the DefaultOpenPath directory read from the
|
||||
* preferences, failing that the working directory. The file format filter
|
||||
* will be set to the DefaultOpenType from the preferences, failing that
|
||||
* the first format specified in the dialogue. These two parameters will
|
||||
* be saved to the preferences once the user has chosen a file to open.
|
||||
* @param extraformat Specify the name of an additional format to allow
|
||||
* opening in this dialogue. This string is free-form, but should be short
|
||||
* enough to fit in the file dialogue filter drop-down. It should be
|
||||
* translated.
|
||||
* @param extrafilter Specify the file extension(s) for the additional format
|
||||
* specified by extraformat. The patterns must include the wildcard (e.g.
|
||||
* "*.aup" not "aup" or ".aup"), separate multiple patters with a semicolon,
|
||||
* e.g. "*.aup;*.AUP" because patterns are case-sensitive. Do not add a
|
||||
* trailing semicolon to the string. This string should not be translated
|
||||
* @return Array of file paths which the user selected to open (multiple
|
||||
* selections allowed).
|
||||
*/
|
||||
static wxArrayString ShowOpenDialog(wxString extraformat = wxEmptyString,
|
||||
wxString extrafilter = wxEmptyString);
|
||||
static void OpenFiles(AudacityProject *proj);
|
||||
void OpenFile(wxString fileName, bool addtohistory = true);
|
||||
bool WarnOfLegacyFile( );
|
||||
|
||||
// If pNewTrackList is passed in non-NULL, it gets filled with the pointers to new tracks.
|
||||
bool Import(wxString fileName, WaveTrackArray *pTrackArray = NULL);
|
||||
|
||||
void AddImportedTracks(wxString fileName,
|
||||
Track **newTracks, int numTracks);
|
||||
bool Save(bool overwrite = true, bool fromSaveAs = false, bool bWantSaveCompressed = false);
|
||||
bool SaveAs(bool bWantSaveCompressed = false);
|
||||
#ifdef USE_LIBVORBIS
|
||||
bool SaveCompressedWaveTracks(const wxString strProjectPathName); // full path for aup except extension
|
||||
#endif
|
||||
void Clear();
|
||||
|
||||
wxString GetFileName() { return mFileName; }
|
||||
bool GetDirty() { return mDirty; }
|
||||
void SetProjectTitle();
|
||||
|
||||
TrackPanel * GetTrackPanel(){return mTrackPanel;};
|
||||
|
||||
bool GetIsEmpty() { return mTracks->IsEmpty(); }
|
||||
|
||||
bool GetTracksFitVerticallyZoomed() { return mTracksFitVerticallyZoomed; } //lda
|
||||
void SetTracksFitVerticallyZoomed(bool flag) { mTracksFitVerticallyZoomed = flag; } //lda
|
||||
|
||||
bool GetShowId3Dialog() { return mShowId3Dialog; } //lda
|
||||
void SetShowId3Dialog(bool flag) { mShowId3Dialog = flag; } //lda
|
||||
|
||||
bool GetCleanSpeechMode() { return mCleanSpeechMode; } //lda
|
||||
void SetCleanSpeechMode(bool flag) { mCleanSpeechMode = flag; } //lda
|
||||
|
||||
bool GetNormalizeOnLoad() { return mNormalizeOnLoad; } //lda
|
||||
void SetNormalizeOnLoad(bool flag) { mNormalizeOnLoad = flag; } //lda
|
||||
|
||||
#include "Menus.h"
|
||||
|
||||
CommandManager *GetCommandManager() { return &mCommandManager; }
|
||||
|
||||
void RebuildMenuBar();
|
||||
void RebuildOtherMenus();
|
||||
void MayStartMonitoring();
|
||||
|
||||
public:
|
||||
|
||||
// Message Handlers
|
||||
|
||||
void OnMenuEvent(wxMenuEvent & event);
|
||||
void OnMenu(wxCommandEvent & event);
|
||||
void OnUpdateUI(wxUpdateUIEvent & event);
|
||||
|
||||
void OnActivate(wxActivateEvent & event);
|
||||
void OnMouseEvent(wxMouseEvent & event);
|
||||
void OnIconize(wxIconizeEvent &event);
|
||||
void OnSize(wxSizeEvent & event);
|
||||
void OnMove(wxMoveEvent & event);
|
||||
void OnScroll(wxScrollEvent & event);
|
||||
void OnCloseWindow(wxCloseEvent & event);
|
||||
void OnTimer(wxTimerEvent & event);
|
||||
void OnToolBarUpdate(wxCommandEvent & event);
|
||||
void OnOpenAudioFile(wxCommandEvent & event);
|
||||
void OnCaptureKeyboard(wxCommandEvent & event);
|
||||
void OnReleaseKeyboard(wxCommandEvent & event);
|
||||
void OnODTaskUpdate(wxCommandEvent & event);
|
||||
void OnODTaskComplete(wxCommandEvent & event);
|
||||
void OnTrackListUpdated(wxCommandEvent & event);
|
||||
bool HandleKeyDown(wxKeyEvent & event);
|
||||
bool HandleChar(wxKeyEvent & event);
|
||||
bool HandleKeyUp(wxKeyEvent & event);
|
||||
|
||||
void HandleResize();
|
||||
void UpdateLayout();
|
||||
|
||||
// Other commands
|
||||
|
||||
static void DeleteClipboard();
|
||||
static void DeleteAllProjectsDeleteLock();
|
||||
|
||||
void UpdateMenus();
|
||||
void UpdatePrefs();
|
||||
void UpdatePrefsVariables();
|
||||
void RedrawProject(const bool bForceWaveTracks = false);
|
||||
void RefreshCursor();
|
||||
void SelectNone();
|
||||
void SelectAllIfNone();
|
||||
void Zoom(double level);
|
||||
void Rewind(bool shift);
|
||||
void SkipEnd(bool shift);
|
||||
void SetStop(bool bStopped);
|
||||
void EditByLabel( WaveTrack::EditFunction action, bool groupIteration );
|
||||
void EditClipboardByLabel( WaveTrack::EditDestFunction action );
|
||||
bool IsSticky();
|
||||
bool GetStickyFlag() { return mStickyFlag; };
|
||||
void SetStickyFlag(bool flag) { mStickyFlag = flag; };
|
||||
|
||||
// "exclusive" mute means mute the chosen track and unmute all others.
|
||||
void HandleTrackMute(Track *t, const bool exclusive);
|
||||
|
||||
// Type of solo (standard or simple) follows the set preference, unless
|
||||
// alternate == true, which causes the opposite behavior.
|
||||
void HandleTrackSolo(Track *t, const bool alternate);
|
||||
|
||||
// Snap To
|
||||
|
||||
void SetSnapTo(bool state);
|
||||
bool GetSnapTo();
|
||||
|
||||
// Scrollbars
|
||||
|
||||
void OnScrollLeft();
|
||||
void OnScrollRight();
|
||||
|
||||
void OnScrollLeftButton(wxScrollEvent & event);
|
||||
void OnScrollRightButton(wxScrollEvent & event);
|
||||
|
||||
void FinishAutoScroll();
|
||||
void FixScrollbars();
|
||||
|
||||
void SafeDisplayStatusMessage(const wxChar *msg);
|
||||
|
||||
// TrackPanel access
|
||||
virtual wxSize GetTPTracksUsableArea();
|
||||
virtual void RefreshTPTrack(Track* pTrk, bool refreshbacking = true);
|
||||
|
||||
// TrackPanel callback methods, overrides of TrackPanelListener
|
||||
virtual void TP_DisplaySelection();
|
||||
virtual void TP_DisplayStatusMessage(wxString msg);
|
||||
|
||||
virtual int TP_GetCurrentTool();
|
||||
virtual ToolsToolBar * TP_GetToolsToolBar();
|
||||
virtual ControlToolBar * TP_GetControlToolBar();
|
||||
|
||||
virtual void TP_OnPlayKey();
|
||||
virtual void TP_PushState(wxString longDesc, wxString shortDesc,
|
||||
bool consolidate);
|
||||
virtual void TP_ModifyState();
|
||||
virtual void TP_RedrawScrollbars();
|
||||
virtual void TP_ScrollLeft();
|
||||
virtual void TP_ScrollRight();
|
||||
virtual void TP_ScrollWindow(double scrollto);
|
||||
virtual void TP_ScrollUpDown(int delta);
|
||||
virtual void TP_HandleResize();
|
||||
|
||||
// ToolBar
|
||||
|
||||
ControlToolBar *GetControlToolBar();
|
||||
DeviceToolBar *GetDeviceToolBar();
|
||||
EditToolBar *GetEditToolBar();
|
||||
MeterToolBar *GetMeterToolBar();
|
||||
MixerToolBar *GetMixerToolBar();
|
||||
SelectionBar *GetSelectionBar();
|
||||
ToolsToolBar *GetToolsToolBar();
|
||||
TranscriptionToolBar *GetTranscriptionToolBar();
|
||||
|
||||
#ifdef EXPERIMENTAL_LYRICS_WINDOW
|
||||
LyricsWindow* GetLyricsWindow() { return mLyricsWindow; };
|
||||
#endif
|
||||
#ifdef EXPERIMENTAL_MIXER_BOARD
|
||||
MixerBoard* GetMixerBoard() { return mMixerBoard; };
|
||||
#endif
|
||||
|
||||
// SelectionBar callback methods
|
||||
|
||||
virtual void AS_SetRate(double rate);
|
||||
virtual void AS_ModifySelection(double &start, double &end);
|
||||
virtual void AS_SetSnapTo(bool state);
|
||||
virtual bool AS_GetSnapTo();
|
||||
|
||||
void SetStateTo(unsigned int n);
|
||||
|
||||
// XMLTagHandler callback methods
|
||||
|
||||
virtual bool HandleXMLTag(const wxChar *tag, const wxChar **attrs);
|
||||
virtual XMLTagHandler *HandleXMLChild(const wxChar *tag);
|
||||
virtual void WriteXML(XMLWriter &xmlFile);
|
||||
|
||||
void WriteXMLHeader(XMLWriter &xmlFile);
|
||||
|
||||
PlayMode mLastPlayMode;
|
||||
ViewInfo mViewInfo;
|
||||
|
||||
wxWindow *HasKeyboardCapture();
|
||||
void CaptureKeyboard(wxWindow *h);
|
||||
void ReleaseKeyboard(wxWindow *h);
|
||||
|
||||
// Audio IO callback methods
|
||||
virtual void OnAudioIORate(int rate);
|
||||
virtual void OnAudioIOStartRecording();
|
||||
virtual void OnAudioIOStopRecording();
|
||||
virtual void OnAudioIONewBlockFiles(const wxString& blockFileLog);
|
||||
|
||||
// Command Handling
|
||||
bool TryToMakeActionAllowed( wxUint32 & flags, wxUint32 flagsRqd, wxUint32 mask );
|
||||
|
||||
///Prevents delete from external thread - for e.g. use of GetActiveProject
|
||||
static void AllProjectsDeleteLock();
|
||||
static void AllProjectsDeleteUnlock();
|
||||
|
||||
void PushState(wxString desc, wxString shortDesc,
|
||||
bool consolidate = false);
|
||||
|
||||
private:
|
||||
|
||||
void ClearClipboard();
|
||||
void InitialState();
|
||||
void ModifyState();
|
||||
void PopState(TrackList * l);
|
||||
|
||||
#ifdef EXPERIMENTAL_LYRICS_WINDOW
|
||||
void UpdateLyrics();
|
||||
#endif
|
||||
#ifdef EXPERIMENTAL_MIXER_BOARD
|
||||
void UpdateMixerBoard();
|
||||
#endif
|
||||
|
||||
void GetRegionsByLabel( Regions ®ions );
|
||||
|
||||
void AutoSaveIfNeeded();
|
||||
void AutoSave();
|
||||
static bool IsAutoSaveEnabled();
|
||||
void DeleteCurrentAutoSaveFile();
|
||||
|
||||
static bool GetCacheBlockFiles();
|
||||
|
||||
public:
|
||||
bool IsSoloSimple() { return mSoloPref == wxT("Simple"); };
|
||||
bool IsSoloNone() { return mSoloPref == wxT("None"); };
|
||||
|
||||
private:
|
||||
|
||||
// The project's name and file info
|
||||
wxString mFileName;
|
||||
DirManager *mDirManager; // MM: DirManager now created dynamically
|
||||
|
||||
double mRate;
|
||||
sampleFormat mDefaultFormat;
|
||||
|
||||
// Recent files
|
||||
wxMenu *mRecentFilesMenu;
|
||||
|
||||
// Tags (artist name, song properties, MP3 ID3 info, etc.)
|
||||
Tags *mTags;
|
||||
|
||||
// List of tracks and display info
|
||||
TrackList *mTracks;
|
||||
|
||||
bool mSnapTo;
|
||||
|
||||
TrackList *mLastSavedTracks;
|
||||
|
||||
// Clipboard (static because it is shared by all projects)
|
||||
static TrackList *msClipboard;
|
||||
static AudacityProject *msClipProject;
|
||||
static double msClipLen;
|
||||
|
||||
//shared by all projects
|
||||
static ODLock *msAllProjectDeleteMutex;
|
||||
|
||||
// History/Undo manager
|
||||
UndoManager mUndoManager;
|
||||
bool mDirty;
|
||||
|
||||
// Commands
|
||||
|
||||
CommandManager mCommandManager;
|
||||
|
||||
wxUint32 mLastFlags;
|
||||
|
||||
// Window elements
|
||||
|
||||
wxTimer *mTimer;
|
||||
long mLastStatusUpdateTime;
|
||||
|
||||
wxStatusBar *mStatusBar;
|
||||
|
||||
AdornedRulerPanel *mRuler;
|
||||
TrackPanel *mTrackPanel;
|
||||
TrackFactory *mTrackFactory;
|
||||
wxPanel * mMainPanel;
|
||||
wxScrollBar *mHsbar;
|
||||
wxScrollBar *mVsbar;
|
||||
bool mAutoScrolling;
|
||||
bool mActive;
|
||||
bool mIconized;
|
||||
|
||||
HistoryWindow *mHistoryWindow;
|
||||
#ifdef EXPERIMENTAL_LYRICS_WINDOW
|
||||
LyricsWindow* mLyricsWindow;
|
||||
#endif
|
||||
#ifdef EXPERIMENTAL_MIXER_BOARD
|
||||
MixerBoard* mMixerBoard;
|
||||
MixerBoardFrame* mMixerBoardFrame;
|
||||
#endif
|
||||
|
||||
FreqWindow *mFreqWindow;
|
||||
|
||||
public:
|
||||
ToolManager *mToolManager;
|
||||
bool mShowSplashScreen;
|
||||
wxString mHelpPref;
|
||||
wxString mSoloPref;
|
||||
|
||||
void SetNormalizedWindowState(wxRect pSizeAndLocation) { mNormalizedWindowState = pSizeAndLocation; }
|
||||
wxRect GetNormalizedWindowState() const { return mNormalizedWindowState; }
|
||||
|
||||
bool IsTimerRecordCancelled(){return mTimerRecordCanceled;}
|
||||
void ResetTimerRecordFlag(){mTimerRecordCanceled=false;}
|
||||
private:
|
||||
|
||||
int mAudioIOToken;
|
||||
|
||||
bool mIsDeleting;
|
||||
bool mTracksFitVerticallyZoomed; //lda
|
||||
bool mNormalizeOnLoad; //lda
|
||||
bool mCleanSpeechMode; //lda
|
||||
bool mShowId3Dialog; //lda
|
||||
bool mEmptyCanBeDirty;
|
||||
bool mSelectAllOnNone;
|
||||
|
||||
bool mStickyFlag;
|
||||
|
||||
bool mLockPlayRegion;
|
||||
|
||||
// See AudacityProject::OnActivate() for an explanation of this.
|
||||
wxWindow *mLastFocusedWindow;
|
||||
|
||||
wxWindow *mKeyboardCaptured;
|
||||
|
||||
ImportXMLTagHandler* mImportXMLTagHandler;
|
||||
|
||||
// Last auto-save file name and path (empty if none)
|
||||
wxString mAutoSaveFileName;
|
||||
|
||||
// When the last auto-save took place (as returned wx wxGetLocalTime)
|
||||
long mLastAutoSaveTime;
|
||||
|
||||
// Are we currently auto-saving or not?
|
||||
bool mAutoSaving;
|
||||
|
||||
// Has this project been recovered from an auto-saved version
|
||||
bool mIsRecovered;
|
||||
|
||||
// The auto-save data dir the project has been recovered from
|
||||
wxString mRecoveryAutoSaveDataDir;
|
||||
|
||||
// The handler that handles recovery of <recordingrecovery> tags
|
||||
RecordingRecoveryHandler* mRecordingRecoveryHandler;
|
||||
|
||||
// Dependencies have been imported and a warning should be shown on save
|
||||
bool mImportedDependencies;
|
||||
|
||||
bool mWantSaveCompressed;
|
||||
wxArrayString mStrOtherNamesArray; // used to make sure compressed file names are unique
|
||||
|
||||
// Last effect applied to this project
|
||||
Effect *mLastEffect;
|
||||
int mLastEffectType;
|
||||
|
||||
// The screenshot class needs to access internals
|
||||
friend class ScreenshotCommand;
|
||||
|
||||
wxRect mNormalizedWindowState;
|
||||
|
||||
//flag for cancellation of timer record.
|
||||
bool mTimerRecordCanceled;
|
||||
|
||||
public:
|
||||
DECLARE_EVENT_TABLE()
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
// Indentation settings for Vim and Emacs and unique identifier for Arch, a
|
||||
// version control system. Please do not modify past this point.
|
||||
//
|
||||
// Local Variables:
|
||||
// c-basic-offset: 3
|
||||
// indent-tabs-mode: nil
|
||||
// End:
|
||||
//
|
||||
// vim: et sts=3 sw=3
|
||||
// arch-tag: bf2e4288-d3d3-411e-b8af-1e8d12814c70
|
||||
|
||||
Reference in New Issue
Block a user