Hi everybody,

Here is a patch (based on 1a09828) which add chords and scales list for
piano-roll, as suggested by Raine M. Ekman.
In detail:

   - 2 combobox added, one for scale list and the other for chords list
   - When a chord is selected:
      - left click on the matrix: add all the chord notes with current key
      as lower note.
      - shift + left click on the matrix: idem, except that notes make an
      arpeggio from lower to upper note.
      - right click on keyboard: context menu which allow marking chord
      semitones.
   - When a scale is selected, a right click on keyboard allow via the
   context menu to mark scale semitones for each octaves.


This patch needs 2 custom graphics. Currently scale.png and chord.png are
copy of note.png.

The goal of the second commit is to bypass the fixed initial width, so if
you are agree with that behavior...

regards
From e14d2d0adf8ab1d6ce2000799279d598dd3b769a Mon Sep 17 00:00:00 2001
From: NoiseByNorthwest <[email protected]>
Date: Wed, 1 Feb 2012 15:09:49 +0100
Subject: [PATCH 1/2] Piano-roll: scale & arpeggio combobox + micro
 refactoring of ChordCreator::Chord

---
 data/themes/default/chord.png    |  Bin 0 -> 1006 bytes
 data/themes/default/scale.png    |  Bin 0 -> 1006 bytes
 include/InstrumentFunctions.h    |   91 +++++++++++--
 include/piano_roll.h             |   29 +++--
 src/core/InstrumentFunctions.cpp |  279 +++++++++++++++++++++++---------------
 src/gui/piano_roll.cpp           |  206 +++++++++++++++++++++-------
 6 files changed, 425 insertions(+), 180 deletions(-)
 create mode 100644 data/themes/default/chord.png
 create mode 100644 data/themes/default/scale.png

diff --git a/data/themes/default/chord.png b/data/themes/default/chord.png
new file mode 100644
index 0000000000000000000000000000000000000000..3f475b0ea497624eca88f9553b2ad24ad16105a5
GIT binary patch
literal 1006
zcmV<K0}=d*P)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv00009a7bBm000XU
z000XU0RWnu7ytkO2XskIMF-Xb77Zg9q8xJ7000AxNkl<ZNXM;}O>Y}j6o#KWo{SwQ
zF)_wzJ}Q#N#Z?8OidB=iA7l~KM5;>VsHspkR6>Xam5^Y=qVNm4CLkmhRAocfksv~C
zC89KP3J42`>)I}j6Wb|va60a|8P5z0rVxUX3?E0jtGPPQdCz&z9dHtH+IW)>06*Xb
zBpimz(XD6cjh~Hwy6j(mO8-Xx2@4Hq02cp42+lElW$B7FyF6?4zSo=J0H=TepzNi_
z<p?l9^!&*AiAYC;_+Y$Si)yc=L+OYf&=uAxq5h%9`ZoZHD6xs*iI>}yHcVkM*fZ!F
zkB%P<4TsKnMm%q<hF71_lll)lq`tj%&J@HrIevV6EURUiE6vf>)`clddb~Xhbq^^6
zk%8y0`L4wpUo_?b70@3;oB>|o`01h3r;^nqm*2UZTWDSIE_;^c^k$m8mB**}aD`l5
zsjpJ&tdRpY00TgFIA%#TRfH^HiJwy!QZuPw%8Nt`9-2AIzQ9Bv%!|ZG@+DBTRhZ5I
zI$EVsL28m<9~P^8PmzrMRUu1rdAj^0A@&32*3LKsR9U;P-$!vP5W>f|s6Ynz6%c@o
ziI+4Upl+Xk04Q;1<-rP_N+%qm!`^1g9;jhMDt6_<c9Q87V38n`U&~h&zw!i!=|B*`
zqQzdat+q7&?r|pom3sbO{$|N6K|gN#I1Kpg0>yuSi$JLDs=FSopQ$z1pn%SIB!B|&
zXty^>+H;G?=;RzH$dNDIF8zWFIKe@n%T}>#4tdAKZ*lfW<jC8{!pCC$-Tf|M2(oIH
zndTYpM(_IR;yDW3vOV9}d4;yeOSprh!A~xZU7Q^089_(_AqkK`2!SCCrnD)pzI!#n
z$Gi_L0M*B?*=q)({q^>#OYuvuhW%k`R*f1pR7<61)u>V>XXXet1z9u~TeQ!$n?N3T
zu+tp=+M){_9gU5?=9b+Q^&-M0z=E<>X7<r62{VD#q=6eykbxl3Y8Ptk1(4(e@?>A2
zPZaec!V*}f#k@Mt_08)vl*aFgWjoz8D^C7sTLHq`>V3LmR1giphOxm7?FI#@@MmJ#
z_RNQr`HZdYF&w!_EvV^aElF7_lQA=xiV012#S)OB!AInnW*(DUz>mQCP6OWVB8mO<
zG07B%IEfz*1|}6WGF17RRTjC;Cij3PAPHn`1&#p1e#H8L2oSOd*Z^vFr3GNcK4swH
cZpi_D1H;c(2iYA_mH+?%07*qoM6N<$f}%IdzyJUM

literal 0
HcmV?d00001

diff --git a/data/themes/default/scale.png b/data/themes/default/scale.png
new file mode 100644
index 0000000000000000000000000000000000000000..3f475b0ea497624eca88f9553b2ad24ad16105a5
GIT binary patch
literal 1006
zcmV<K0}=d*P)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv00009a7bBm000XU
z000XU0RWnu7ytkO2XskIMF-Xb77Zg9q8xJ7000AxNkl<ZNXM;}O>Y}j6o#KWo{SwQ
zF)_wzJ}Q#N#Z?8OidB=iA7l~KM5;>VsHspkR6>Xam5^Y=qVNm4CLkmhRAocfksv~C
zC89KP3J42`>)I}j6Wb|va60a|8P5z0rVxUX3?E0jtGPPQdCz&z9dHtH+IW)>06*Xb
zBpimz(XD6cjh~Hwy6j(mO8-Xx2@4Hq02cp42+lElW$B7FyF6?4zSo=J0H=TepzNi_
z<p?l9^!&*AiAYC;_+Y$Si)yc=L+OYf&=uAxq5h%9`ZoZHD6xs*iI>}yHcVkM*fZ!F
zkB%P<4TsKnMm%q<hF71_lll)lq`tj%&J@HrIevV6EURUiE6vf>)`clddb~Xhbq^^6
zk%8y0`L4wpUo_?b70@3;oB>|o`01h3r;^nqm*2UZTWDSIE_;^c^k$m8mB**}aD`l5
zsjpJ&tdRpY00TgFIA%#TRfH^HiJwy!QZuPw%8Nt`9-2AIzQ9Bv%!|ZG@+DBTRhZ5I
zI$EVsL28m<9~P^8PmzrMRUu1rdAj^0A@&32*3LKsR9U;P-$!vP5W>f|s6Ynz6%c@o
ziI+4Upl+Xk04Q;1<-rP_N+%qm!`^1g9;jhMDt6_<c9Q87V38n`U&~h&zw!i!=|B*`
zqQzdat+q7&?r|pom3sbO{$|N6K|gN#I1Kpg0>yuSi$JLDs=FSopQ$z1pn%SIB!B|&
zXty^>+H;G?=;RzH$dNDIF8zWFIKe@n%T}>#4tdAKZ*lfW<jC8{!pCC$-Tf|M2(oIH
zndTYpM(_IR;yDW3vOV9}d4;yeOSprh!A~xZU7Q^089_(_AqkK`2!SCCrnD)pzI!#n
z$Gi_L0M*B?*=q)({q^>#OYuvuhW%k`R*f1pR7<61)u>V>XXXet1z9u~TeQ!$n?N3T
zu+tp=+M){_9gU5?=9b+Q^&-M0z=E<>X7<r62{VD#q=6eykbxl3Y8Ptk1(4(e@?>A2
zPZaec!V*}f#k@Mt_08)vl*aFgWjoz8D^C7sTLHq`>V3LmR1giphOxm7?FI#@@MmJ#
z_RNQr`HZdYF&w!_EvV^aElF7_lQA=xiV012#S)OB!AInnW*(DUz>mQCP6OWVB8mO<
zG07B%IEfz*1|}6WGF17RRTjC;Cij3PAPHn`1&#p1e#H8L2oSOd*Z^vFr3GNcK4swH
cZpi_D1H;c(2iYA_mH+?%07*qoM6N<$f}%IdzyJUM

literal 0
HcmV?d00001

diff --git a/include/InstrumentFunctions.h b/include/InstrumentFunctions.h
index 43a73bb..8520aca 100644
--- a/include/InstrumentFunctions.h
+++ b/include/InstrumentFunctions.h
@@ -36,12 +36,17 @@ class InstrumentTrack;
 class notePlayHandle;
 
 
-const int MAX_CHORD_POLYPHONY = 10;
-
 
 class ChordCreator : public Model, public JournallingObject
 {
 	Q_OBJECT
+
+public:
+	static const int MAX_CHORD_POLYPHONY = 10;
+
+private:
+	typedef Sint8 ChordSemiTones [MAX_CHORD_POLYPHONY];
+
 public:
 	ChordCreator( Model * _parent );
 	virtual ~ChordCreator();
@@ -58,22 +63,84 @@ public:
 	}
 
 
-	static struct Chord
+	struct Chord
 	{
-		const QString name;
-		Sint8 interval[MAX_CHORD_POLYPHONY];
-	} s_chordTable[];
+	private:
+		QString m_name;
+		ChordSemiTones m_semiTones;
+		int m_size;
+
+	public:
+		Chord() : m_size( 0 ) {}
+
+		Chord( const char * n, const ChordSemiTones & semi_tones );
+
+		int size() const
+		{
+			return m_size;
+		}
+
+		bool isScale() const
+		{
+			return size() > 6;
+		}
+
+		bool isEmpty() const
+		{
+			return size() == 0;
+		}
+
+		bool hasSemiTone( Sint8 semi_tone ) const;
 
+		Sint8 last() const
+		{
+			return m_semiTones[size() - 1];
+		}
 
-	static inline int getChordSize( Chord & _c )
+		const QString & getName() const
+		{
+			return m_name;
+		}
+
+		Sint8 operator [] ( int n ) const
+		{
+			return m_semiTones[n];
+		}
+	};
+
+
+	struct ChordTable : public QVector<Chord>
 	{
-		int idx = 0;
-		while( _c.interval[idx] != -1 )
+	private:
+		ChordTable();
+
+		struct Init
 		{
-			++idx;
+			const char * m_name;
+			ChordSemiTones m_semiTones;
+		};
+
+		static Init s_initTable[];
+
+	public:
+		static const ChordTable & getInstance()
+		{
+			static ChordTable inst;
+			return inst;
 		}
-		return idx;
-	}
+
+		const Chord & getByName( const QString & name, bool is_scale = false ) const;
+
+		const Chord & getScaleByName( const QString & name ) const
+		{
+			return getByName( name, true );
+		}
+
+		const Chord & getChordByName( const QString & name ) const
+		{
+			return getByName( name, false );
+		}
+	};
 
 
 private:
diff --git a/include/piano_roll.h b/include/piano_roll.h
index 7780875..3bb1c5d 100644
--- a/include/piano_roll.h
+++ b/include/piano_roll.h
@@ -139,9 +139,16 @@ protected slots:
 
 	void zoomingChanged();
 	void quantizeChanged();
-		
+
+	void updateSemiToneMarkerMenu();
+
 	void changeNoteEditMode( int i );
-	void markTone( int i );
+	void markSemiTone( int i );
+
+
+signals:
+	void semiToneMarkerMenuScaleSetEnabled(bool);
+	void semiToneMarkerMenuChordSetEnabled(bool);
 
 
 private:
@@ -171,12 +178,12 @@ private:
 		NoteEditCount // make sure this one is always last
 	};
 
-	enum toneMarkerAction
+	enum semiToneMarkerAction
 	{
-		tmmeUnmarkAll,
-		tmmeMarkCurrent,
-		tmmeMarkMinorScale,
-		tmmeMarkMajorScale,
+		stmaUnmarkAll,
+		stmaMarkCurrentSemiTone,
+		stmaMarkCurrentScale,
+		stmaMarkCurrentChord,
 	};
 
 	enum pianoRollKeyTypes
@@ -189,8 +196,8 @@ private:
 	QVector<QString> m_nemStr; // gui names of each edit mode
 	QMenu * m_noteEditMenu; // when you right click below the key area
 
-	QList<int> m_markedTones;
-	QMenu * m_toneMarkerMenu; // when you right click on the key area
+	QList<int> m_markedSemiTones;
+	QMenu * m_semiToneMarkerMenu; // when you right click on the key area
 
 	pianoRoll();
 	pianoRoll( const pianoRoll & );
@@ -251,10 +258,14 @@ private:
 	comboBox * m_zoomingComboBox;
 	comboBox * m_quantizeComboBox;
 	comboBox * m_noteLenComboBox;
+	comboBox * m_scaleComboBox;
+	comboBox * m_chordComboBox;
 
 	ComboBoxModel m_zoomingModel;
 	ComboBoxModel m_quantizeModel;
 	ComboBoxModel m_noteLenModel;
+	ComboBoxModel m_scaleModel;
+	ComboBoxModel m_chordModel;
 
 
 
diff --git a/src/core/InstrumentFunctions.cpp b/src/core/InstrumentFunctions.cpp
index d806f22..a209663 100644
--- a/src/core/InstrumentFunctions.cpp
+++ b/src/core/InstrumentFunctions.cpp
@@ -33,118 +33,177 @@
 
 
 
-ChordCreator::Chord ChordCreator::s_chordTable[] =
+ChordCreator::ChordTable::Init ChordCreator::ChordTable::s_initTable[] =
 {
-	{ ChordCreator::tr( "octave" ), { 0, -1 } },
-	{ ChordCreator::tr( "Major" ), { 0, 4, 7, -1 } },
-	{ ChordCreator::tr( "Majb5" ), { 0, 4, 6, -1 } },
-	{ ChordCreator::tr( "minor" ), { 0, 3, 7, -1 } },
-	{ ChordCreator::tr( "minb5" ), { 0, 3, 6, -1 } },
-	{ ChordCreator::tr( "sus2" ), { 0, 2, 7, -1 } },
-	{ ChordCreator::tr( "sus4" ), { 0, 5, 7, -1 } },
-	{ ChordCreator::tr( "aug" ), { 0, 4, 8, -1 } },
-	{ ChordCreator::tr( "augsus4" ), { 0, 5, 8, -1 } },
-	{ ChordCreator::tr( "tri" ), { 0, 3, 6, 9, -1 } },
+	{ "octave", { 0, -1 } },
+	{ "Major" , { 0, 4, 7, -1 } },
+	{ "Majb5" , { 0, 4, 6, -1 } },
+	{ "minor" , { 0, 3, 7, -1 } },
+	{ "minb5" , { 0, 3, 6, -1 } },
+	{ "sus2" , { 0, 2, 7, -1 } },
+	{ "sus4" , { 0, 5, 7, -1 } },
+	{ "aug" , { 0, 4, 8, -1 } },
+	{ "augsus4" , { 0, 5, 8, -1 } },
+	{ "tri" , { 0, 3, 6, 9, -1 } },
 	
-	{ ChordCreator::tr( "6" ), { 0, 4, 7, 9, -1 } },
-	{ ChordCreator::tr( "6sus4" ), { 0, 5, 7, 9, -1 } },
-	{ ChordCreator::tr( "6add9" ), { 0, 4, 7, 12, -1 } },
-	{ ChordCreator::tr( "m6" ), { 0, 3, 7, 9, -1 } },
-	{ ChordCreator::tr( "m6add9" ), { 0, 3, 7, 9, 14, -1 } },
-
-	{ ChordCreator::tr( "7" ), { 0, 4, 7, 10, -1 } },
-	{ ChordCreator::tr( "7sus4" ), { 0, 5, 7, 10, -1 } },
-	{ ChordCreator::tr( "7#5" ), { 0, 4, 8, 10, -1 } },
-	{ ChordCreator::tr( "7b5" ), { 0, 4, 6, 10, -1 } },
-	{ ChordCreator::tr( "7#9" ), { 0, 4, 7, 10, 13, 18, -1 } },
-	{ ChordCreator::tr( "7b9" ), { 0, 4, 7, 10, 13, 16, -1 } },
-	{ ChordCreator::tr( "7#5#9" ), { 0, 4, 8, 12, 14, 19, -1 } },
-	{ ChordCreator::tr( "7#5b9" ), { 0, 4, 8, 12, 14, 17, -1 } },
-	{ ChordCreator::tr( "7b5b9" ), { 0, 4, 6, 10, 12, 15, -1 } },
-	{ ChordCreator::tr( "7add11" ), { 0, 4, 7, 10, 17, -1 } },
-	{ ChordCreator::tr( "7add13" ), { 0, 4, 7, 10, 21, -1 } },
-	{ ChordCreator::tr( "7#11" ), { 0, 4, 7, 10, 18, -1 } },
-	{ ChordCreator::tr( "Maj7" ), { 0, 4, 7, 11, -1 } },
-	{ ChordCreator::tr( "Maj7b5" ), { 0, 4, 6, 11, -1 } },
-	{ ChordCreator::tr( "Maj7#5" ), { 0, 4, 8, 11, -1 } },
-	{ ChordCreator::tr( "Maj7#11" ), { 0, 4, 7, 11, 18, -1 } },
-	{ ChordCreator::tr( "Maj7add13" ), { 0, 4, 7, 11, 21, -1 } },
-	{ ChordCreator::tr( "m7" ), { 0, 3, 7, 10, -1 } },
-	{ ChordCreator::tr( "m7b5" ), { 0, 3, 6, 10, -1 } },
-	{ ChordCreator::tr( "m7b9" ), { 0, 3, 7, 10, 13, -1 } },
-	{ ChordCreator::tr( "m7add11" ), { 0, 3, 7, 10, 17, -1 } },
-	{ ChordCreator::tr( "m7add13" ), { 0, 3, 7, 10, 21, -1 } },
-	{ ChordCreator::tr( "m-Maj7" ), { 0, 3, 7, 11, -1 } },
-	{ ChordCreator::tr( "m-Maj7add11" ), { 0, 3, 7, 11, 17, -1 } },
-	{ ChordCreator::tr( "m-Maj7add13" ), { 0, 3, 7, 11, 21, -1 } },
-
-	{ ChordCreator::tr( "9" ), { 0, 4, 7, 10, 14, -1 } },
-	{ ChordCreator::tr( "9sus4" ), { 0, 5, 7, 10, 14, -1 } },
-	{ ChordCreator::tr( "add9" ), { 0, 4, 7, 14, -1 } },
-	{ ChordCreator::tr( "9#5" ), { 0, 4, 8, 10, 14, -1 } },
-	{ ChordCreator::tr( "9b5" ), { 0, 4, 6, 10, 14, -1 } },
-	{ ChordCreator::tr( "9#11" ), { 0, 4, 7, 10, 14, 18, -1 } },
-	{ ChordCreator::tr( "9b13" ), { 0, 4, 7, 10, 14, 20, -1 } },
-	{ ChordCreator::tr( "Maj9" ), { 0, 4, 7, 11, 14, -1 } },
-	{ ChordCreator::tr( "Maj9sus4" ), { 0, 5, 7, 11, 15, -1 } },
-	{ ChordCreator::tr( "Maj9#5" ), { 0, 4, 8, 11, 14, -1 } },
-	{ ChordCreator::tr( "Maj9#11" ), { 0, 4, 7, 11, 14, 18, -1 } },
-	{ ChordCreator::tr( "m9" ), { 0, 3, 7, 10, 14, -1 } },
-	{ ChordCreator::tr( "madd9" ), { 0, 3, 7, 14, -1 } },
-	{ ChordCreator::tr( "m9b5" ), { 0, 3, 6, 10, 14, -1 } },
-	{ ChordCreator::tr( "m9-Maj7" ), { 0, 3, 7, 11, 14, -1 } },
-
-	{ ChordCreator::tr( "11" ), { 0, 4, 7, 10, 14, 17, -1 } },
-	{ ChordCreator::tr( "11b9" ), { 0, 4, 7, 10, 13, 17, -1 } },
-	{ ChordCreator::tr( "Maj11" ), { 0, 4, 7, 11, 14, 17, -1 } },
-	{ ChordCreator::tr( "m11" ), { 0, 3, 7, 10, 14, 17, -1 } },
-	{ ChordCreator::tr( "m-Maj11" ), { 0, 3, 7, 11, 14, 17, -1 } },
-
-	{ ChordCreator::tr( "13" ), { 0, 4, 7, 10, 14, 21, -1 } },
-	{ ChordCreator::tr( "13#9" ), { 0, 4, 7, 10, 15, 21, -1 } },
-	{ ChordCreator::tr( "13b9" ), { 0, 4, 7, 10, 13, 21, -1 } },
-	{ ChordCreator::tr( "13b5b9" ), { 0, 4, 6, 10, 13, 21, -1 } },
-	{ ChordCreator::tr( "Maj13" ), { 0, 4, 7, 11, 14, 21, -1 } },
-	{ ChordCreator::tr( "m13" ), { 0, 3, 7, 10, 14, 21, -1 } },
-	{ ChordCreator::tr( "m-Maj13" ), { 0, 3, 7, 11, 14, 21, -1 } },
-
-	{ ChordCreator::tr( "Major" ), { 0, 2, 4, 5, 7, 9, 11, -1 } },
-	{ ChordCreator::tr( "Harmonic minor" ), { 0, 2, 3, 5, 7, 8, 11, -1 } },
-	{ ChordCreator::tr( "Melodic minor" ), { 0, 2, 3, 5, 7, 9, 11, -1 } },
-	{ ChordCreator::tr( "Whole tone" ), { 0, 2, 4, 6, 8, 10, -1 } },
-	{ ChordCreator::tr( "Diminished" ), { 0, 2, 3, 5, 6, 8, 9, 11, -1 } },
-	{ ChordCreator::tr( "Major pentatonic" ), { 0, 2, 4, 7, 10, -1 } },
-	{ ChordCreator::tr( "Minor pentatonic" ), { 0, 3, 5, 7, 10, -1 } },
-	{ ChordCreator::tr( "Jap in sen" ), { 0, 1, 5, 7, 10, -1 } },
-	{ ChordCreator::tr( "Major bebop" ), { 0, 2, 4, 5, 7, 8, 9, 11, -1 } },
-	{ ChordCreator::tr( "Dominant bebop" ), { 0, 2, 4, 5, 7, 9, 10, 11, -1 } },
-	{ ChordCreator::tr( "Blues" ), { 0, 3, 5, 6, 7, 10, -1 } },
-	{ ChordCreator::tr( "Arabic" ), { 0, 1, 4, 5, 7, 8, 11, -1 } },
-	{ ChordCreator::tr( "Enigmatic" ), { 0, 1, 4, 6, 8, 10, 11, -1 } },
-	{ ChordCreator::tr( "Neopolitan" ), { 0, 1, 3, 5, 7, 9, 11, -1 } },
-	{ ChordCreator::tr( "Neopolitan minor" ), { 0, 1, 3, 5, 7, 9, 11, -1 } },
-	{ ChordCreator::tr( "Hungarian minor" ), { 0, 2, 3, 6, 7, 9, 11, -1 } },
-	{ ChordCreator::tr( "Dorian" ), { 0, 2, 3, 5, 7, 9, 10, -1 } },
-	{ ChordCreator::tr( "Phrygolydian" ), { 0, 1, 3, 5, 7, 8, 10, -1 } },
-	{ ChordCreator::tr( "Lydian" ), { 0, 2, 4, 6, 7, 9, 11, -1 } },
-	{ ChordCreator::tr( "Mixolydian" ), { 0, 2, 4, 5, 7, 9, 10, -1 } },
-	{ ChordCreator::tr( "Aeolian" ), { 0, 2, 3, 5, 7, 8, 10, -1 } },
-	{ ChordCreator::tr( "Locrian" ), { 0, 1, 3, 5, 6, 8, 10, -1 } },
-
-	{ "", { -1, -1 } }
-
+	{ "6" , { 0, 4, 7, 9, -1 } },
+	{ "6sus4" , { 0, 5, 7, 9, -1 } },
+	{ "6add9" , { 0, 4, 7, 12, -1 } },
+	{ "m6" , { 0, 3, 7, 9, -1 } },
+	{ "m6add9" , { 0, 3, 7, 9, 14, -1 } },
+
+	{ "7" , { 0, 4, 7, 10, -1 } },
+	{ "7sus4" , { 0, 5, 7, 10, -1 } },
+	{ "7#5" , { 0, 4, 8, 10, -1 } },
+	{ "7b5" , { 0, 4, 6, 10, -1 } },
+	{ "7#9" , { 0, 4, 7, 10, 13, 18, -1 } },
+	{ "7b9" , { 0, 4, 7, 10, 13, 16, -1 } },
+	{ "7#5#9" , { 0, 4, 8, 12, 14, 19, -1 } },
+	{ "7#5b9" , { 0, 4, 8, 12, 14, 17, -1 } },
+	{ "7b5b9" , { 0, 4, 6, 10, 12, 15, -1 } },
+	{ "7add11" , { 0, 4, 7, 10, 17, -1 } },
+	{ "7add13" , { 0, 4, 7, 10, 21, -1 } },
+	{ "7#11" , { 0, 4, 7, 10, 18, -1 } },
+	{ "Maj7" , { 0, 4, 7, 11, -1 } },
+	{ "Maj7b5" , { 0, 4, 6, 11, -1 } },
+	{ "Maj7#5" , { 0, 4, 8, 11, -1 } },
+	{ "Maj7#11" , { 0, 4, 7, 11, 18, -1 } },
+	{ "Maj7add13" , { 0, 4, 7, 11, 21, -1 } },
+	{ "m7" , { 0, 3, 7, 10, -1 } },
+	{ "m7b5" , { 0, 3, 6, 10, -1 } },
+	{ "m7b9" , { 0, 3, 7, 10, 13, -1 } },
+	{ "m7add11" , { 0, 3, 7, 10, 17, -1 } },
+	{ "m7add13" , { 0, 3, 7, 10, 21, -1 } },
+	{ "m-Maj7" , { 0, 3, 7, 11, -1 } },
+	{ "m-Maj7add11" , { 0, 3, 7, 11, 17, -1 } },
+	{ "m-Maj7add13" , { 0, 3, 7, 11, 21, -1 } },
+
+	{ "9" , { 0, 4, 7, 10, 14, -1 } },
+	{ "9sus4" , { 0, 5, 7, 10, 14, -1 } },
+	{ "add9" , { 0, 4, 7, 14, -1 } },
+	{ "9#5" , { 0, 4, 8, 10, 14, -1 } },
+	{ "9b5" , { 0, 4, 6, 10, 14, -1 } },
+	{ "9#11" , { 0, 4, 7, 10, 14, 18, -1 } },
+	{ "9b13" , { 0, 4, 7, 10, 14, 20, -1 } },
+	{ "Maj9" , { 0, 4, 7, 11, 14, -1 } },
+	{ "Maj9sus4" , { 0, 5, 7, 11, 15, -1 } },
+	{ "Maj9#5" , { 0, 4, 8, 11, 14, -1 } },
+	{ "Maj9#11" , { 0, 4, 7, 11, 14, 18, -1 } },
+	{ "m9" , { 0, 3, 7, 10, 14, -1 } },
+	{ "madd9" , { 0, 3, 7, 14, -1 } },
+	{ "m9b5" , { 0, 3, 6, 10, 14, -1 } },
+	{ "m9-Maj7" , { 0, 3, 7, 11, 14, -1 } },
+
+	{ "11" , { 0, 4, 7, 10, 14, 17, -1 } },
+	{ "11b9" , { 0, 4, 7, 10, 13, 17, -1 } },
+	{ "Maj11" , { 0, 4, 7, 11, 14, 17, -1 } },
+	{ "m11" , { 0, 3, 7, 10, 14, 17, -1 } },
+	{ "m-Maj11" , { 0, 3, 7, 11, 14, 17, -1 } },
+
+	{ "13" , { 0, 4, 7, 10, 14, 21, -1 } },
+	{ "13#9" , { 0, 4, 7, 10, 15, 21, -1 } },
+	{ "13b9" , { 0, 4, 7, 10, 13, 21, -1 } },
+	{ "13b5b9" , { 0, 4, 6, 10, 13, 21, -1 } },
+	{ "Maj13" , { 0, 4, 7, 11, 14, 21, -1 } },
+	{ "m13" , { 0, 3, 7, 10, 14, 21, -1 } },
+	{ "m-Maj13" , { 0, 3, 7, 11, 14, 21, -1 } },
+
+	{ "Major" , { 0, 2, 4, 5, 7, 9, 11, -1 } },
+	{ "Harmonic minor" , { 0, 2, 3, 5, 7, 8, 11, -1 } },
+	{ "Melodic minor" , { 0, 2, 3, 5, 7, 9, 11, -1 } },
+	{ "Whole tone" , { 0, 2, 4, 6, 8, 10, -1 } },
+	{ "Diminished" , { 0, 2, 3, 5, 6, 8, 9, 11, -1 } },
+	{ "Major pentatonic" , { 0, 2, 4, 7, 10, -1 } },
+	{ "Minor pentatonic" , { 0, 3, 5, 7, 10, -1 } },
+	{ "Jap in sen" , { 0, 1, 5, 7, 10, -1 } },
+	{ "Major bebop" , { 0, 2, 4, 5, 7, 8, 9, 11, -1 } },
+	{ "Dominant bebop" , { 0, 2, 4, 5, 7, 9, 10, 11, -1 } },
+	{ "Blues" , { 0, 3, 5, 6, 7, 10, -1 } },
+	{ "Arabic" , { 0, 1, 4, 5, 7, 8, 11, -1 } },
+	{ "Enigmatic" , { 0, 1, 4, 6, 8, 10, 11, -1 } },
+	{ "Neopolitan" , { 0, 1, 3, 5, 7, 9, 11, -1 } },
+	{ "Neopolitan minor" , { 0, 1, 3, 5, 7, 8, 11, -1 } },
+	{ "Hungarian minor" , { 0, 2, 3, 6, 7, 8, 11, -1 } },
+	{ "Dorian" , { 0, 2, 3, 5, 7, 9, 10, -1 } },
+	{ "Phrygolydian" , { 0, 1, 3, 5, 7, 8, 10, -1 } },
+	{ "Lydian" , { 0, 2, 4, 6, 7, 9, 11, -1 } },
+	{ "Mixolydian" , { 0, 2, 4, 5, 7, 9, 10, -1 } },
+	{ "Aeolian" , { 0, 2, 3, 5, 7, 8, 10, -1 } },
+	{ "Locrian" , { 0, 1, 3, 5, 6, 8, 10, -1 } },
 } ;
 
 
+
+
+ChordCreator::Chord::Chord( const char * n, const ChordSemiTones & semi_tones ) :
+	m_name( tr( n ) )
+{
+	for( m_size = 0; m_size < MAX_CHORD_POLYPHONY; m_size++ )
+	{
+		if( semi_tones[m_size] == -1 )
+		{
+			break;
+		}
+
+		m_semiTones[m_size] = semi_tones[m_size];
+	}
+}
+
+
+
+
+bool ChordCreator::Chord::hasSemiTone( Sint8 semi_tone ) const
+{
+	for( int i = 0; i < size(); ++i )
+	{
+		if( semi_tone == m_semiTones[i] )
+			return true;
+	}
+	return false;
+}
+
+
+
+
+ChordCreator::ChordTable::ChordTable() :
+	QVector<Chord>()
+{
+	for( int i = 0;
+		i < static_cast<int>( sizeof s_initTable / sizeof *s_initTable );
+		i++ )
+	{
+		push_back( Chord( s_initTable[i].m_name, s_initTable[i].m_semiTones ) );
+	}
+}
+
+
+
+
+const ChordCreator::Chord & ChordCreator::ChordTable::getByName( const QString & name, bool is_scale ) const
+{
+	for( int i = 0; i < size(); i++ )
+	{
+		if( at( i ).getName() == name && is_scale == at( i ).isScale() )
+			return at( i );
+	}
+
+	static Chord empty;
+	return empty;
+}
+
+
+
+
 ChordCreator::ChordCreator( Model * _parent ) :
 	Model( _parent, tr( "Chords" ) ),
 	m_chordsEnabledModel( false, this ),
 	m_chordsModel( this, tr( "Chord type" ) ),
 	m_chordRangeModel( 1.0f, 1.0f, 9.0f, 1.0f, this, tr( "Chord range" ) )
 {
-	for( int i = 0; s_chordTable[i].interval[0] != -1; ++i )
+	const ChordTable & chord_table = ChordTable::getInstance();
+	for( int i = 0; i < chord_table.size(); ++i )
 	{
-		m_chordsModel.addItem( tr( s_chordTable[i].name.toUtf8().
+		m_chordsModel.addItem( tr( chord_table[i].getName().toUtf8().
 								constData() ) );
 	}
 }
@@ -162,6 +221,7 @@ ChordCreator::~ChordCreator()
 void ChordCreator::processNote( notePlayHandle * _n )
 {
 	const int base_note_key = _n->key();
+	const ChordTable & chord_table = ChordTable::getInstance();
 	// we add chord-subnotes to note if either note is a base-note and
 	// arpeggio is not used or note is part of an arpeggio
 	// at the same time we only add sub-notes if nothing of the note was
@@ -186,13 +246,13 @@ void ChordCreator::processNote( notePlayHandle * _n )
 			// create it in the following loop, then we loop until
 			// there's a -1 in the interval-array
 			for( int i = ( octave_cnt == 0 ) ? 1 : 0;
-				s_chordTable[selected_chord].interval[i] != -1;
+				i < chord_table[selected_chord].size();
 									++i )
 			{
 				// add interval to sub-note-key
 				const int sub_note_key = sub_note_key_base +
-							(int) s_chordTable[
-						selected_chord].interval[i];
+							(int) chord_table[
+						selected_chord][i];
 				// maybe we're out of range -> let's get outta
 				// here!
 				if( sub_note_key > NumKeys )
@@ -255,11 +315,11 @@ Arpeggiator::Arpeggiator( Model * _parent ) :
 	m_arpDirectionModel( this, tr( "Arpeggio direction" ) ),
 	m_arpModeModel( this, tr( "Arpeggio mode" ) )
 {
-	for( int i = 0; ChordCreator::s_chordTable[i].interval[0] != -1; ++i )
+	const ChordCreator::ChordTable & chord_table = ChordCreator::ChordTable::getInstance();
+	for( int i = 0; i < chord_table[i].size(); ++i )
 	{
 		m_arpModel.addItem( ChordCreator::tr(
-					ChordCreator::s_chordTable[i].
-						name.toUtf8().constData() ) );
+					chord_table[i].getName().toUtf8().constData() ) );
 	}
 
 	m_arpDirectionModel.addItem( tr( "Up" ), new PixmapLoader( "arp_up" ) );
@@ -314,8 +374,8 @@ void Arpeggiator::processNote( notePlayHandle * _n )
 		}
 	}
 
-	const int cur_chord_size = ChordCreator::getChordSize(
-				ChordCreator::s_chordTable[selected_arp] );
+	const ChordCreator::ChordTable & chord_table = ChordCreator::ChordTable::getInstance();
+	const int cur_chord_size = chord_table[selected_arp].size();
 	const int range = (int)( cur_chord_size * m_arpRangeModel.value() );
 	const int total_range = range * cnphv.size();
 
@@ -401,8 +461,7 @@ void Arpeggiator::processNote( notePlayHandle * _n )
 		const int sub_note_key = base_note_key + (cur_arp_idx /
 							cur_chord_size ) *
 							KeysPerOctave +
-				ChordCreator::s_chordTable[selected_arp].
-					interval[cur_arp_idx % cur_chord_size];
+				chord_table[selected_arp][cur_arp_idx % cur_chord_size];
 
 		// range-checking
 		if( sub_note_key >= NumKeys ||
diff --git a/src/gui/piano_roll.cpp b/src/gui/piano_roll.cpp
index 3ad36cc..0674e53 100644
--- a/src/gui/piano_roll.cpp
+++ b/src/gui/piano_roll.cpp
@@ -138,7 +138,7 @@ const int DEFAULT_PR_PPT = KEY_LINE_HEIGHT * DefaultStepsPerTact;
 pianoRoll::pianoRoll() :
 	m_nemStr( QVector<QString>() ),
 	m_noteEditMenu( NULL ),
-	m_toneMarkerMenu( NULL ),
+	m_semiToneMarkerMenu( NULL ),
 	m_zoomingModel(),
 	m_quantizeModel(),
 	m_noteLenModel(),
@@ -187,30 +187,34 @@ pianoRoll::pianoRoll() :
 			this, SLOT(changeNoteEditMode(int)) );
 	
 	signalMapper = new QSignalMapper( this );
-	m_toneMarkerMenu = new QMenu( this );
+	m_semiToneMarkerMenu = new QMenu( this );
 
-	QAction * act = new QAction( tr("Mark/unmark current tone"), this );
+	QAction * act = new QAction( tr("Mark/unmark current semitone"), this );
 	connect( act, SIGNAL(triggered()), signalMapper, SLOT(map()) );
-	signalMapper->setMapping( act, static_cast<int>( tmmeMarkCurrent ) );
-	m_toneMarkerMenu->addAction( act );
+	signalMapper->setMapping( act, static_cast<int>( stmaMarkCurrentSemiTone ) );
+	m_semiToneMarkerMenu->addAction( act );
 
-	act = new QAction( tr("Mark minor scale"), this );
+	act = new QAction( tr("Mark current scale"), this );
+	act->setEnabled( false );
 	connect( act, SIGNAL(triggered()), signalMapper, SLOT(map()) );
-	signalMapper->setMapping( act, static_cast<int>( tmmeMarkMinorScale ) );
-	m_toneMarkerMenu->addAction( act );
+	connect( this, SIGNAL(semiToneMarkerMenuScaleSetEnabled(bool)), act, SLOT(setEnabled(bool)) );
+	signalMapper->setMapping( act, static_cast<int>( stmaMarkCurrentScale ) );
+	m_semiToneMarkerMenu->addAction( act );
 
-	act = new QAction( tr("Mark major scale"), this );
+	act = new QAction( tr("Mark current chord"), this );
+	act->setEnabled( false );
 	connect( act, SIGNAL(triggered()), signalMapper, SLOT(map()) );
-	signalMapper->setMapping( act, static_cast<int>( tmmeMarkMajorScale ) );
-	m_toneMarkerMenu->addAction( act );
+	connect( this, SIGNAL(semiToneMarkerMenuChordSetEnabled(bool)), act, SLOT(setEnabled(bool)) );
+	signalMapper->setMapping( act, static_cast<int>( stmaMarkCurrentChord ) );
+	m_semiToneMarkerMenu->addAction( act );
 
 	act = new QAction( tr("Unmark all"), this );
 	connect( act, SIGNAL(triggered()), signalMapper, SLOT(map()) );
-	signalMapper->setMapping( act, static_cast<int>( tmmeUnmarkAll ) );
-	m_toneMarkerMenu->addAction( act );
+	signalMapper->setMapping( act, static_cast<int>( stmaUnmarkAll ) );
+	m_semiToneMarkerMenu->addAction( act );
 
 	connect( signalMapper, SIGNAL(mapped(int)),
-			this, SLOT(markTone(int)) );
+			this, SLOT(markSemiTone(int)) );
 
 	// init pixmaps
 	if( s_whiteKeySmallPm == NULL )
@@ -498,6 +502,52 @@ pianoRoll::pianoRoll() :
 					this, SLOT( quantizeChanged() ) );
 
 
+	const ChordCreator::ChordTable & chord_table = ChordCreator::ChordTable::getInstance();
+
+	// setup scale-stuff
+	QLabel * scale_lbl = new QLabel( m_toolBar );
+	scale_lbl->setPixmap( embed::getIconPixmap( "scale" ) );
+
+	m_scaleModel.addItem( tr("No scale") );
+	for( int i = 0; i < chord_table.size(); ++i )
+	{
+		if( chord_table[i].isScale() )
+		{
+			m_scaleModel.addItem( chord_table[i].getName() );
+		}
+	}
+
+	m_scaleModel.setValue( 0 );
+	m_scaleComboBox = new comboBox( m_toolBar );
+	m_scaleComboBox->setModel( &m_scaleModel );
+	m_scaleComboBox->setFixedSize( 105, 22 );
+	// change can update m_semiToneMarkerMenu
+	connect( &m_scaleModel, SIGNAL( dataChanged() ),
+					this, SLOT( updateSemiToneMarkerMenu() ) );
+
+
+	// setup chord-stuff
+	QLabel * chord_lbl = new QLabel( m_toolBar );
+	chord_lbl->setPixmap( embed::getIconPixmap( "chord" ) );
+
+	m_chordModel.addItem( tr("No chord") );
+	for( int i = 0; i < chord_table.size(); ++i )
+	{
+		if( ! chord_table[i].isScale() )
+		{
+			m_chordModel.addItem( chord_table[i].getName() );
+		}
+	}
+
+	m_chordModel.setValue( 0 );
+	m_chordComboBox = new comboBox( m_toolBar );
+	m_chordComboBox->setModel( &m_chordModel );
+	m_chordComboBox->setFixedSize( 105, 22 );
+	// change can update m_semiToneMarkerMenu
+	connect( &m_chordModel, SIGNAL( dataChanged() ),
+					this, SLOT( updateSemiToneMarkerMenu() ) );
+
+
 	tb_layout->addSpacing( 5 );
 	tb_layout->addWidget( m_playButton );
 	tb_layout->addWidget( m_recordButton );
@@ -526,6 +576,14 @@ pianoRoll::pianoRoll() :
 	tb_layout->addWidget( note_len_lbl );
 	tb_layout->addSpacing( 4 );
 	tb_layout->addWidget( m_noteLenComboBox );
+	tb_layout->addSpacing( 10 );
+	tb_layout->addWidget( scale_lbl );
+	tb_layout->addSpacing( 4 );
+	tb_layout->addWidget( m_scaleComboBox );
+	tb_layout->addSpacing( 10 );
+	tb_layout->addWidget( chord_lbl );
+	tb_layout->addSpacing( 4 );
+	tb_layout->addWidget( m_chordComboBox );
 	tb_layout->addStretch();
 
 	// setup our actual window
@@ -564,60 +622,69 @@ void pianoRoll::changeNoteEditMode( int i )
 }
 
 
-void pianoRoll::markTone( int i )
+void pianoRoll::markSemiTone( int i )
 {
-	static const int major_scale[KeysPerOctave] = {
-		1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1
-	};
-
-	static const int minor_scale[KeysPerOctave] = {
-		1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0
-	};
-
-	const int * scale = 0;
-	const int key = getKey( mapFromGlobal( m_toneMarkerMenu->pos() ).y() );
+	const int key = getKey( mapFromGlobal( m_semiToneMarkerMenu->pos() ).y() );
+	const ChordCreator::Chord * chord = 0;
 
-	switch( static_cast<toneMarkerAction>( i ) )
+	switch( static_cast<semiToneMarkerAction>( i ) )
 	{
-		case tmmeUnmarkAll:
-			m_markedTones.clear();
+		case stmaUnmarkAll:
+			m_markedSemiTones.clear();
 			break;
-		case tmmeMarkCurrent:
+		case stmaMarkCurrentSemiTone:
 		{
-			QList<int>::iterator i = qFind( m_markedTones.begin(), m_markedTones.end(), key );
-			if( i != m_markedTones.end() )
+			QList<int>::iterator i = qFind( m_markedSemiTones.begin(), m_markedSemiTones.end(), key );
+			if( i != m_markedSemiTones.end() )
 			{
-				m_markedTones.erase( i );
+				m_markedSemiTones.erase( i );
 			}
 			else
 			{
-				m_markedTones.push_back( key );
+				m_markedSemiTones.push_back( key );
 			}
 			break;
 		}
-		case tmmeMarkMinorScale:
-			scale = minor_scale;
-		case tmmeMarkMajorScale:
-			if( ! scale )
+		case stmaMarkCurrentScale:
+			chord = & ChordCreator::ChordTable::getInstance()
+					.getScaleByName( m_scaleModel.currentText() );
+		case stmaMarkCurrentChord:
+		{
+			if( ! chord )
 			{
-				scale = major_scale;
+				chord = & ChordCreator::ChordTable::getInstance()
+						.getChordByName( m_chordModel.currentText() );
 			}
 
-			for( int i = 0; i <= NumKeys; i++ )
+			if( chord->isEmpty() )
 			{
-				if( scale[std::abs( key - i ) % KeysPerOctave] )
+				break;
+			}
+			else if( chord->isScale() )
+			{
+				m_markedSemiTones.clear();
+			}
+
+			const int first = chord->isScale() ? 0 : key;
+			const int last = chord->isScale() ? NumKeys : key + chord->last();
+			const int cap = chord->isScale() ? KeysPerOctave : chord->last();
+
+			for( int i = first; i <= last; i++ )
+			{
+				if( chord->hasSemiTone( std::abs( key - i ) % cap ) )
 				{
-					m_markedTones.push_back( i );
+					m_markedSemiTones.push_back( i );
 				}
 			}
 			break;
+		}
 		default:
 			;
 	}
 
-	qSort( m_markedTones.begin(), m_markedTones.end(), qGreater<int>() );
-	QList<int>::iterator new_end = std::unique( m_markedTones.begin(), m_markedTones.end() );
-	m_markedTones.erase( new_end, m_markedTones.end() );
+	qSort( m_markedSemiTones.begin(), m_markedSemiTones.end(), qGreater<int>() );
+	QList<int>::iterator new_end = std::unique( m_markedSemiTones.begin(), m_markedSemiTones.end() );
+	m_markedSemiTones.erase( new_end, m_markedSemiTones.end() );
 }
 
 
@@ -1453,11 +1520,15 @@ void pianoRoll::mousePressEvent( QMouseEvent * _me )
 			else if( _me->button() == Qt::LeftButton &&
 							m_editMode == ModeDraw )
 			{
+				// whether this action creates new note(s) or not
+				bool is_new_note = false;
+
 				note * created_new_note = NULL;
 				// did it reach end of vector because
 				// there's no note??
 				if( it == notes.begin()-1 )
 				{
+					is_new_note = true;
 					m_pattern->setType( pattern::MelodyPattern );
 
 					// then set new note
@@ -1470,13 +1541,35 @@ void pianoRoll::mousePressEvent( QMouseEvent * _me )
 					// because live notes should still be quantized at the half.
 					midiTime note_pos( pos_ticks - ( quantization() / 2 ) );
 					midiTime note_len( newNoteLen() );
-		
+
 					note new_note( note_len, note_pos, key_num );
 					new_note.setSelected( true );
 					new_note.setPanning( m_lastNotePanning );
 					new_note.setVolume( m_lastNoteVolume );
 					created_new_note = m_pattern->addNote( new_note );
 
+					const ChordCreator::Chord & chord = ChordCreator::ChordTable::getInstance()
+						.getChordByName( m_chordModel.currentText() );
+
+					if( ! chord.isEmpty() )
+					{
+						// if a chord is selected, create following notes in chord
+						// or arpeggio mode
+						const bool arpeggio = _me->modifiers() & Qt::ShiftModifier;
+						for( int i = 1; i < chord.size(); i++ )
+						{
+							if( arpeggio )
+							{
+								note_pos += note_len;
+							}
+							note new_note( note_len, note_pos, key_num + chord[i] );
+							new_note.setSelected( true );
+							new_note.setPanning( m_lastNotePanning );
+							new_note.setVolume( m_lastNoteVolume );
+							m_pattern->addNote( new_note );
+						}
+					}
+
 					// reset it so that it can be used for
 					// ops (move, resize) after this
 					// code-block
@@ -1579,7 +1672,7 @@ void pianoRoll::mousePressEvent( QMouseEvent * _me )
 					
 					// if they're holding shift, copy all selected notes 
 					if( //*it != created_new_note &&
-					   _me->modifiers() & Qt::ShiftModifier )
+					   ! is_new_note && _me->modifiers() & Qt::ShiftModifier )
 					{
 						// vector to hold new notes until we're through the loop
 						QVector<note> newNotes;
@@ -1662,7 +1755,7 @@ void pianoRoll::mousePressEvent( QMouseEvent * _me )
 			if( _me->buttons() == Qt::RightButton )
 			{
 				// right click, tone marker contextual menu
-				m_toneMarkerMenu->popup( mapToGlobal( QPoint( _me->x(), _me->y() ) ) );
+				m_semiToneMarkerMenu->popup( mapToGlobal( QPoint( _me->x(), _me->y() ) ) );
 			}
 			else
 			{
@@ -2703,9 +2796,9 @@ void pianoRoll::paintEvent( QPaintEvent * _pe )
 	}
 
 	// display note marks
-	for( int i = 0; i < m_markedTones.size(); i++ )
+	for( int i = 0; i < m_markedSemiTones.size(); i++ )
 	{
-		const int key_num = m_markedTones.at( i );
+		const int key_num = m_markedSemiTones.at( i );
 		const int y = keyAreaBottom() + 5
 			- KEY_LINE_HEIGHT * ( key_num - m_startKey + 1 );
 
@@ -3673,6 +3766,21 @@ int pianoRoll::quantization() const
 
 
 
+void pianoRoll::updateSemiToneMarkerMenu()
+{
+	const ChordCreator::Chord & scale = ChordCreator::ChordTable::getInstance()
+					.getScaleByName( m_scaleModel.currentText() );
+
+	const ChordCreator::Chord & chord = ChordCreator::ChordTable::getInstance()
+					.getChordByName( m_chordModel.currentText() );
+
+	emit semiToneMarkerMenuScaleSetEnabled( ! scale.isEmpty() );
+	emit semiToneMarkerMenuChordSetEnabled( ! chord.isEmpty() );
+}
+
+
+
+
 midiTime pianoRoll::newNoteLen() const
 {
 	if( m_noteLenModel.value() == 0 )
-- 
1.7.5.4


From 2182f54675271d07390ef491b43ade45e34b01be Mon Sep 17 00:00:00 2001
From: NoiseByNorthwest <[email protected]>
Date: Wed, 1 Feb 2012 15:10:52 +0100
Subject: [PATCH 2/2] Piano-roll: bypass fixed initial width of the window

---
 src/gui/piano_roll.cpp |    5 ++---
 1 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/src/gui/piano_roll.cpp b/src/gui/piano_roll.cpp
index 0674e53..d41e5b0 100644
--- a/src/gui/piano_roll.cpp
+++ b/src/gui/piano_roll.cpp
@@ -76,7 +76,6 @@ extern Keys whiteKeys[];	// defined in piano_widget.cpp
 
 
 // some constants...
-const int INITIAL_PIANOROLL_WIDTH = 840;
 const int INITIAL_PIANOROLL_HEIGHT = 480;
 
 const int SCROLLBAR_SIZE = 16;
@@ -600,13 +599,13 @@ pianoRoll::pianoRoll() :
 	if( engine::mainWindow()->workspace() )
 	{
 		engine::mainWindow()->workspace()->addSubWindow( this );
-		parentWidget()->resize( INITIAL_PIANOROLL_WIDTH,
+		parentWidget()->resize( tb_layout->minimumSize().width(),
 						INITIAL_PIANOROLL_HEIGHT );
 		parentWidget()->hide();
 	}
 	else
 	{
-		resize( INITIAL_PIANOROLL_WIDTH, INITIAL_PIANOROLL_HEIGHT );
+		resize( tb_layout->minimumSize().width(), INITIAL_PIANOROLL_HEIGHT );
 		hide();
 	}
 
-- 
1.7.5.4

------------------------------------------------------------------------------
Keep Your Developer Skills Current with LearnDevNow!
The most comprehensive online learning library for Microsoft developers
is just $99.99! Visual Studio, SharePoint, SQL - plus HTML5, CSS3, MVC3,
Metro Style Apps, more. Free future releases when you subscribe now!
http://p.sf.net/sfu/learndevnow-d2d
_______________________________________________
LMMS-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/lmms-devel

Reply via email to