You can subscribe to this list here.
| 2009 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(25) |
Jul
(288) |
Aug
(119) |
Sep
(31) |
Oct
(59) |
Nov
(458) |
Dec
(359) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2010 |
Jan
(268) |
Feb
(26) |
Mar
(36) |
Apr
(48) |
May
(119) |
Jun
(37) |
Jul
(173) |
Aug
(429) |
Sep
(137) |
Oct
(156) |
Nov
(59) |
Dec
(45) |
| 2011 |
Jan
(398) |
Feb
(257) |
Mar
(49) |
Apr
(5) |
May
(34) |
Jun
(11) |
Jul
(38) |
Aug
(12) |
Sep
(1) |
Oct
(49) |
Nov
(5) |
Dec
(10) |
| 2012 |
Jan
(21) |
Feb
(32) |
Mar
(20) |
Apr
(1) |
May
(2) |
Jun
|
Jul
(173) |
Aug
|
Sep
(25) |
Oct
(6) |
Nov
(44) |
Dec
|
|
From: Tapio V. <aa...@us...> - 2011-01-26 14:24:55
|
Module: editor Branch: master Commit: 598c25343fc339350a57cfac48edab320e2bd85f Author: Tapio Vierros <tap...@gm...> Date: Wed Jan 26 16:23:56 2011 +0200 Replaced boost::thread with QThread in FFmpeg. --- CMakeLists.txt | 3 +- ffmpeg.cc | 45 +++++++++++++++++++-------------------- ffmpeg.hh | 64 ++++++++++++++++++++++++------------------------------- xtime.hh | 29 ------------------------- 4 files changed, 51 insertions(+), 90 deletions(-) |
|
From: Tapio V. <aa...@us...> - 2011-01-26 10:37:35
|
Module: editor
Branch: master
Commit: a7dff611f9190d89c97a99ccca77757fb0d4ce2e
Author: Tapio Vierros <tap...@gm...>
Date: Wed Jan 26 12:36:19 2011 +0200
Synchronous FFmpeg opening: no more waiting for duration availability.
---
ffmpeg.cc | 13 +++++++------
pitchvis.cc | 7 +------
2 files changed, 8 insertions(+), 12 deletions(-)
diff --git a/ffmpeg.cc b/ffmpeg.cc
index 2c563dd..889a83a 100644
--- a/ffmpeg.cc
+++ b/ffmpeg.cc
@@ -19,9 +19,13 @@ extern "C" {
FFmpeg::FFmpeg(std::string const& _filename, unsigned int rate):
m_filename(_filename), m_rate(rate), m_quit(), m_running(), m_eof(), m_seekTarget(getNaN()),
pFormatCtx(), pResampleCtx(), img_convert_ctx(), pAudioCodecCtx(), pAudioCodec(),
- audioStream(-1), m_position(),
- m_thread(new boost::thread(boost::ref(*this)))
-{}
+ audioStream(-1), m_position()
+{
+ open(); // Throws on error
+ m_running = true;
+ audioQueue.setDuration(duration());
+ m_thread.reset(new boost::thread(boost::ref(*this)));
+}
FFmpeg::~FFmpeg() {
m_quit = true;
@@ -87,9 +91,6 @@ void FFmpeg::open() {
}
void FFmpeg::operator()() {
- try { open(); } catch (std::exception const& e) { std::cerr << "FFMPEG failed to open " << m_filename << ": " << e.what() << std::endl; m_quit = true; return; }
- m_running = true;
- audioQueue.setDuration(duration());
int errors = 0;
while (!m_quit) {
try {
diff --git a/pitchvis.cc b/pitchvis.cc
index be788b3..b2becc4 100644
--- a/pitchvis.cc
+++ b/pitchvis.cc
@@ -29,13 +29,8 @@ void PitchVis::run()
{
// Initialize FFmpeg decoding
FFmpeg mpeg(fileName.toStdString(), rate);
- while(std::isnan(mpeg.duration()) || std::isinf(mpeg.duration())) {
- if (mpeg.terminating()) // Check if FFMPEG has failed
- return;
- msleep(1000); // Wait for ffmpeg to be ready
- }
- msleep(1000); // Wait some more
setWidth(mpeg.duration() * rate / step); // Estimation
+ msleep(1000); // Wait some
curX = 0;
for (std::vector<float> data(step*2); mpeg.audioQueue(&*data.begin(), &*data.end(), curX * step * 2); ++curX) {
msleep(2);
|
|
From: Tapio V. <aa...@us...> - 2011-01-26 10:18:28
|
Module: editor Branch: master Commit: 782ea096da34dcca78caef12618f9f4d6a2c4678 Author: Tapio Vierros <tap...@gm...> Date: Wed Jan 26 12:17:34 2011 +0200 Remove video stuff from FFmpeg to make it simpler. --- ffmpeg.cc | 146 ++++++++++++----------------------------------------------- ffmpeg.hh | 93 +------------------------------------- pitchvis.cc | 2 +- 3 files changed, 31 insertions(+), 210 deletions(-) |
|
From: Tapio V. <aa...@us...> - 2011-01-26 09:15:15
|
Module: editor
Branch: master
Commit: 9e1b5706612a75c06d16027ebf94820898e1e532
Author: Tapio Vierros <tap...@gm...>
Date: Wed Jan 26 11:13:11 2011 +0200
Added a super fancy about dialog.
---
aboutdialog.ui | 115 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
docs/Authors.txt | 8 ++++
editor.qrc | 38 +++++++++--------
editorapp.cc | 34 ++++++++++++++-
editorapp.hh | 10 +++++
5 files changed, 184 insertions(+), 21 deletions(-)
diff --git a/aboutdialog.ui b/aboutdialog.ui
new file mode 100644
index 0000000..58d5322
--- /dev/null
+++ b/aboutdialog.ui
@@ -0,0 +1,115 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>AboutDialog</class>
+ <widget class="QDialog" name="AboutDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>480</width>
+ <height>320</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Dialog</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QTabWidget" name="tabWidget">
+ <widget class="QWidget" name="tab1">
+ <attribute name="title">
+ <string>&About</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <widget class="QLabel" name="lblName">
+ <property name="font">
+ <font>
+ <pointsize>32</pointsize>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string notr="true">ApplicationName</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="lblVersion">
+ <property name="font">
+ <font>
+ <pointsize>16</pointsize>
+ </font>
+ </property>
+ <property name="text">
+ <string notr="true">Version: XY</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="lblDescription">
+ <property name="text">
+ <string>This is an application for creating notes for karaoke games that score the performance based on pitch accuracy.</string>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tab3">
+ <attribute name="title">
+ <string>A&uthors</string>
+ </attribute>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <widget class="QPlainTextEdit" name="txtAuthors">
+ <property name="lineWrapMode">
+ <enum>QPlainTextEdit::NoWrap</enum>
+ </property>
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tab2">
+ <attribute name="title">
+ <string>&License</string>
+ </attribute>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="0" column="0">
+ <widget class="QPlainTextEdit" name="txtLicense">
+ <property name="lineWrapMode">
+ <enum>QPlainTextEdit::NoWrap</enum>
+ </property>
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="cmdClose">
+ <property name="text">
+ <string>&Close</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/docs/Authors.txt b/docs/Authors.txt
new file mode 100644
index 0000000..b35c398
--- /dev/null
+++ b/docs/Authors.txt
@@ -0,0 +1,8 @@
+Primary Authors:
+Lasse Kärkkäinen
+Tapio Vierros
+
+See Git repository history for full list of contributors.
+
+This applications uses code from the Performous game.
+
diff --git a/editor.qrc b/editor.qrc
index e301484..25f0721 100644
--- a/editor.qrc
+++ b/editor.qrc
@@ -1,19 +1,21 @@
-<!DOCTYPE RCC><RCC version="1.0">
-<qresource>
-<file>icons/application-exit.png</file>
-<file>icons/document-new.png</file>
-<file>icons/document-save-as.png</file>
-<file>icons/document-save.png</file>
-<file>icons/edit-redo.png</file>
-<file>icons/edit-undo.png</file>
-<file>icons/green-document-open.png</file>
-<file>icons/help-about.png</file>
-<file>icons/help-hint.png</file>
-<file>icons/insert-object.png</file>
-<file>icons/insert-text.png</file>
-<file>icons/media-playback-pause.png</file>
-<file>icons/media-playback-start.png</file>
-<file>icons/media-playback-stop.png</file>
-<file>icons/preferences-other.png</file>
-</qresource>
+<RCC>
+ <qresource prefix="/">
+ <file>icons/application-exit.png</file>
+ <file>icons/document-new.png</file>
+ <file>icons/document-save-as.png</file>
+ <file>icons/document-save.png</file>
+ <file>icons/edit-redo.png</file>
+ <file>icons/edit-undo.png</file>
+ <file>icons/green-document-open.png</file>
+ <file>icons/help-about.png</file>
+ <file>icons/help-hint.png</file>
+ <file>icons/insert-object.png</file>
+ <file>icons/insert-text.png</file>
+ <file>icons/media-playback-pause.png</file>
+ <file>icons/media-playback-start.png</file>
+ <file>icons/media-playback-stop.png</file>
+ <file>icons/preferences-other.png</file>
+ <file>docs/Authors.txt</file>
+ <file>docs/License.txt</file>
+ </qresource>
</RCC>
diff --git a/editorapp.cc b/editorapp.cc
index 56db07c..857c4a6 100644
--- a/editorapp.cc
+++ b/editorapp.cc
@@ -463,9 +463,8 @@ void EditorApp::on_actionWhatsThis_triggered()
void EditorApp::on_actionAbout_triggered()
{
- QMessageBox::about(this, tr("About"),
- tr("Semi-automatic karaoke song editor.\n")
- );
+ AboutDialog aboutDialog(this);
+ aboutDialog.exec();
}
void EditorApp::updateSongMeta(bool readFromSongToUI)
@@ -600,3 +599,32 @@ void EditorApp::closeEvent(QCloseEvent *event)
if (promptSaving()) event->accept();
else event->ignore();
}
+
+
+AboutDialog::AboutDialog(QWidget* parent)
+ : QDialog(parent)
+{
+ setupUi(this);
+ setWindowTitle(tr("About %1").arg(PACKAGE));
+ // Setup About tab
+ lblName->setText(PACKAGE);
+ lblVersion->setText(QString(tr("Version: ")) + VERSION);
+
+ // Populate Authors tab
+ {
+ QFile f(":/docs/Authors.txt");
+ f.open(QIODevice::ReadOnly);
+ QTextStream in(&f);
+ txtAuthors->setPlainText(in.readAll());
+ }
+ // Poplate License text
+ {
+ QFile f(":/docs/License.txt");
+ f.open(QIODevice::ReadOnly);
+ QTextStream in(&f);
+ txtLicense->setPlainText(in.readAll());
+ }
+
+ connect(cmdClose, SIGNAL(clicked()), this, SLOT(accept()));
+ setModal(true);
+}
diff --git a/editorapp.hh b/editorapp.hh
index ee26dd4..5332042 100644
--- a/editorapp.hh
+++ b/editorapp.hh
@@ -2,6 +2,7 @@
#include <phonon/MediaObject>
#include "ui_editor.h"
+#include "ui_aboutdialog.h"
#include "operation.hh"
#include "song.hh"
@@ -14,6 +15,15 @@ namespace Phonon {
class AudioOutput;
}
+
+class AboutDialog: public QDialog, private Ui::AboutDialog
+{
+ Q_OBJECT
+public:
+ AboutDialog(QWidget* parent = 0);
+};
+
+
class EditorApp: public QMainWindow
{
Q_OBJECT
|
|
From: Tapio V. <aa...@us...> - 2011-01-26 09:15:13
|
Module: editor
Branch: master
Commit: 331277f26fb9d8875ee6cacd875271f96381c8dc
Author: Tapio Vierros <tap...@gm...>
Date: Wed Jan 26 10:19:48 2011 +0200
Provide fallback icons where themes are not available.
---
editor.qrc | 20 +++++++++++++++++++-
editorapp.cc | 33 +++++++++++++++++----------------
icons/application-exit.png | Bin 0 -> 1569 bytes
icons/document-new.png | Bin 0 -> 1248 bytes
icons/document-save-as.png | Bin 0 -> 1342 bytes
icons/document-save.png | Bin 0 -> 968 bytes
icons/edit-redo.png | Bin 0 -> 1330 bytes
icons/edit-undo.png | Bin 0 -> 1398 bytes
icons/green-document-open.png | Bin 0 -> 990 bytes
icons/help-about.png | Bin 0 -> 1471 bytes
icons/help-hint.png | Bin 0 -> 1259 bytes
icons/insert-object.png | Bin 0 -> 1100 bytes
icons/insert-text.png | Bin 0 -> 1066 bytes
icons/media-playback-pause.png | Bin 0 -> 1448 bytes
icons/media-playback-start.png | Bin 0 -> 1474 bytes
icons/media-playback-stop.png | Bin 0 -> 1436 bytes
icons/preferences-other.png | Bin 0 -> 1531 bytes
17 files changed, 36 insertions(+), 17 deletions(-)
diff --git a/editor.qrc b/editor.qrc
index 7646d2b..e301484 100644
--- a/editor.qrc
+++ b/editor.qrc
@@ -1 +1,19 @@
-<RCC/>
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+<file>icons/application-exit.png</file>
+<file>icons/document-new.png</file>
+<file>icons/document-save-as.png</file>
+<file>icons/document-save.png</file>
+<file>icons/edit-redo.png</file>
+<file>icons/edit-undo.png</file>
+<file>icons/green-document-open.png</file>
+<file>icons/help-about.png</file>
+<file>icons/help-hint.png</file>
+<file>icons/insert-object.png</file>
+<file>icons/insert-text.png</file>
+<file>icons/media-playback-pause.png</file>
+<file>icons/media-playback-start.png</file>
+<file>icons/media-playback-stop.png</file>
+<file>icons/preferences-other.png</file>
+</qresource>
+</RCC>
diff --git a/editorapp.cc b/editorapp.cc
index e0972d4..56db07c 100644
--- a/editorapp.cc
+++ b/editorapp.cc
@@ -57,20 +57,21 @@ EditorApp::EditorApp(QWidget *parent): QMainWindow(parent), projectFileName(), h
song.reset(new Song);
// Some icons to make menus etc prettier
- ui.actionNew->setIcon(QIcon::fromTheme("document-new"));
- ui.actionOpen->setIcon(QIcon::fromTheme("document-open"));
- ui.actionSave->setIcon(QIcon::fromTheme("document-save"));
- ui.actionSaveAs->setIcon(QIcon::fromTheme("document-save-as"));
- ui.actionExit->setIcon(QIcon::fromTheme("application-exit"));
- ui.actionUndo->setIcon(QIcon::fromTheme("edit-undo"));
- ui.actionRedo->setIcon(QIcon::fromTheme("edit-redo"));
- ui.actionPreferences->setIcon(QIcon::fromTheme("preferences-other"));
- ui.actionMusicFile->setIcon(QIcon::fromTheme("insert-object"));
- ui.actionLyricsFromFile->setIcon(QIcon::fromTheme("insert-text"));
- ui.actionLyricsFromClipboard->setIcon(QIcon::fromTheme("insert-text"));
- ui.actionAbout->setIcon(QIcon::fromTheme("help-about"));
- ui.cmdPlay->setIcon(QIcon::fromTheme("media-playback-start"));
- ui.cmdStop->setIcon(QIcon::fromTheme("media-playback-stop"));
+ ui.actionNew->setIcon(QIcon::fromTheme("document-new", QIcon(":/icons/document-new.png")));
+ ui.actionOpen->setIcon(QIcon::fromTheme("document-open", QIcon(":/icons/document-open.png")));
+ ui.actionSave->setIcon(QIcon::fromTheme("document-save", QIcon(":/icons/document-save.png")));
+ ui.actionSaveAs->setIcon(QIcon::fromTheme("document-save-as", QIcon(":/icons/document-save-as.png")));
+ ui.actionExit->setIcon(QIcon::fromTheme("application-exit", QIcon(":/icons/application-exit.png")));
+ ui.actionUndo->setIcon(QIcon::fromTheme("edit-undo", QIcon(":/icons/edit-undo.png")));
+ ui.actionRedo->setIcon(QIcon::fromTheme("edit-redo", QIcon(":/icons/edit-redo.png")));
+ ui.actionPreferences->setIcon(QIcon::fromTheme("preferences-other", QIcon(":/icons/preferences-other.png")));
+ ui.actionMusicFile->setIcon(QIcon::fromTheme("insert-object", QIcon(":/icons/insert-object.png")));
+ ui.actionLyricsFromFile->setIcon(QIcon::fromTheme("insert-text", QIcon(":/icons/insert-text.png")));
+ ui.actionLyricsFromClipboard->setIcon(QIcon::fromTheme("insert-text", QIcon(":/icons/insert-text.png")));
+ ui.actionWhatsThis->setIcon(QIcon::fromTheme("help-hint", QIcon(":/icons/help-hint.png")));
+ ui.actionAbout->setIcon(QIcon::fromTheme("help-about", QIcon(":/icons/help-about.png")));
+ ui.cmdPlay->setIcon(QIcon::fromTheme("media-playback-start", QIcon(":/icons/media-playback-start.png")));
+ ui.cmdStop->setIcon(QIcon::fromTheme("media-playback-stop", QIcon(":/icons/media-playback-stop.png")));
statusbarProgress = new QProgressBar(NULL);
ui.statusbar->addPermanentWidget(statusbarProgress);
@@ -511,10 +512,10 @@ void EditorApp::playButton()
{
if (player && player->state() == Phonon::PlayingState) {
ui.cmdPlay->setText(tr("Pause"));
- ui.cmdPlay->setIcon(QIcon::fromTheme("media-playback-pause"));
+ ui.cmdPlay->setIcon(QIcon::fromTheme("media-playback-pause", QIcon(":/icons/media-playback-pause.png")));
} else {
ui.cmdPlay->setText(tr("Play"));
- ui.cmdPlay->setIcon(QIcon::fromTheme("media-playback-start"));
+ ui.cmdPlay->setIcon(QIcon::fromTheme("media-playback-start", QIcon(":/icons/media-playback-start.png")));
}
}
diff --git a/icons/application-exit.png b/icons/application-exit.png
new file mode 100755
index 0000000..974c99f
Binary files /dev/null and b/icons/application-exit.png differ
diff --git a/icons/document-new.png b/icons/document-new.png
new file mode 100755
index 0000000..7460cd1
Binary files /dev/null and b/icons/document-new.png differ
diff --git a/icons/document-save-as.png b/icons/document-save-as.png
new file mode 100755
index 0000000..7538ab6
Binary files /dev/null and b/icons/document-save-as.png differ
diff --git a/icons/document-save.png b/icons/document-save.png
new file mode 100755
index 0000000..6c2e71d
Binary files /dev/null and b/icons/document-save.png differ
diff --git a/icons/edit-redo.png b/icons/edit-redo.png
new file mode 100755
index 0000000..6af7b47
Binary files /dev/null and b/icons/edit-redo.png differ
diff --git a/icons/edit-undo.png b/icons/edit-undo.png
new file mode 100755
index 0000000..cda141f
Binary files /dev/null and b/icons/edit-undo.png differ
diff --git a/icons/green-document-open.png b/icons/green-document-open.png
new file mode 100755
index 0000000..2722e8c
Binary files /dev/null and b/icons/green-document-open.png differ
diff --git a/icons/help-about.png b/icons/help-about.png
new file mode 100755
index 0000000..9b4d9ad
Binary files /dev/null and b/icons/help-about.png differ
diff --git a/icons/help-hint.png b/icons/help-hint.png
new file mode 100755
index 0000000..eb3a53b
Binary files /dev/null and b/icons/help-hint.png differ
diff --git a/icons/insert-object.png b/icons/insert-object.png
new file mode 100755
index 0000000..6389257
Binary files /dev/null and b/icons/insert-object.png differ
diff --git a/icons/insert-text.png b/icons/insert-text.png
new file mode 100755
index 0000000..f765ff6
Binary files /dev/null and b/icons/insert-text.png differ
diff --git a/icons/media-playback-pause.png b/icons/media-playback-pause.png
new file mode 100755
index 0000000..c5202c4
Binary files /dev/null and b/icons/media-playback-pause.png differ
diff --git a/icons/media-playback-start.png b/icons/media-playback-start.png
new file mode 100755
index 0000000..37c4353
Binary files /dev/null and b/icons/media-playback-start.png differ
diff --git a/icons/media-playback-stop.png b/icons/media-playback-stop.png
new file mode 100755
index 0000000..80ece50
Binary files /dev/null and b/icons/media-playback-stop.png differ
diff --git a/icons/preferences-other.png b/icons/preferences-other.png
new file mode 100755
index 0000000..1062aae
Binary files /dev/null and b/icons/preferences-other.png differ
|
|
From: Tapio V. <aa...@us...> - 2011-01-26 07:14:16
|
Module: editor
Branch: master
Commit: 93e11e258aeb76d55645245e667fd0abb42d5a09
Author: Tapio Vierros <tap...@gm...>
Date: Wed Jan 26 09:12:50 2011 +0200
Add a codec selector dialog when wrong encoding is detected.
The "Automatic" option doesn't seem to work. :-(
---
CMakeLists.txt | 2 +-
songparser.cc | 19 +++++++---
textcodecselector.hh | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 110 insertions(+), 6 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5a286f4..6d20b5f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -42,7 +42,7 @@ else(Phonon_FOUND)
endif(Phonon_FOUND)
# Headers that need MOC need to be defined separately
-file(GLOB MOC_HEADER_FILES "editorapp.hh" "notelabel.hh" "notegraphwidget.hh")
+file(GLOB MOC_HEADER_FILES "editorapp.hh" "notelabel.hh" "notegraphwidget.hh" "textcodecselector.hh")
file(GLOB SOURCE_FILES "*.cc")
file(GLOB HEADER_FILES "*.hh")
diff --git a/songparser.cc b/songparser.cc
index bf2bc9b..c917154 100644
--- a/songparser.cc
+++ b/songparser.cc
@@ -1,5 +1,5 @@
#include "songparser.hh"
-
+#include "textcodecselector.hh"
#include <QFile>
#include <QFileInfo>
@@ -37,12 +37,21 @@ SongParser::SongParser(Song& s):
QFileInfo finfo(file);
if (finfo.size() < 10 || finfo.size() > 100000) throw SongParserException("Does not look like a song file (wrong size)", 1, true);
- QTextStream stream(&file);
- QString data = stream.readAll();
+ // Determine encoding
+ QString data;
+ {
+ QByteArray ba = file.readAll();
+ if (!ba.isEmpty()) {
+ data = QString::fromLocal8Bit(ba, ba.size());
+ if (data.toLocal8Bit().size() != ba.size()) {
+ // Not UTF8 :(
+ QTextCodec* codec = TextCodecSelector::codecForContent(ba);
+ if (codec) data = codec->toUnicode(ba);
+ }
+ }
+ }
file.close();
- // TODO: Convert data from unknown encoding
-
if (smCheck(data)) type = SM;
else if (txtCheck(data)) type = TXT;
else if (xmlCheck(data)) type = XML;
diff --git a/textcodecselector.hh b/textcodecselector.hh
new file mode 100644
index 0000000..225a332
--- /dev/null
+++ b/textcodecselector.hh
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2000-2008 TROLLTECH ASA. All rights reserved.
+**
+** This file is part of the Opensource Edition of the Qtopia Toolkit.
+**
+** This software is licensed under the terms of the GNU General Public
+** License (GPL) version 2.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact in...@tr... if any conditions of this licensing are
+** not clear to you.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** Code has been modified from the original.
+****************************************************************************/
+
+#include <QDialog>
+#include <QWidget>
+#include <QListWidget>
+#include <QTextCodec>
+#include <QLabel>
+#include <QVBoxLayout>
+#include <QByteArray>
+
+#include <iostream>
+
+class TextCodecSelector : public QDialog {
+ Q_OBJECT
+public:
+ TextCodecSelector(QWidget* parent = 0)
+ : QDialog(parent)
+ {
+ setWindowTitle(tr("Unknown encoding"));
+ list = new QListWidget(this);
+ connect(list, SIGNAL(itemActivated(QListWidgetItem*)), this, SLOT(accept()));
+ connect(list, SIGNAL(itemPressed(QListWidgetItem*)), this, SLOT(accept()));
+ codecs = QTextCodec::availableCodecs();
+ qSort(codecs);
+ list->addItem(tr("Automatic"));
+ foreach (QByteArray n, codecs) {
+ list->addItem(n);
+ }
+ QLabel *label = new QLabel(tr("<qt>Choose the encoding for this file:</qt>"));
+ label->setWordWrap(true);
+ QVBoxLayout *vb = new QVBoxLayout(this);
+ vb->addWidget(label);
+ vb->addWidget(list);
+ setLayout(vb);
+ }
+
+ QTextCodec *selection(QByteArray ba) const
+ {
+ int n = list->currentRow();
+ if (n < 0) {
+ return 0;
+ } else if (n == 0) {
+ // Automatic... just try them all and pick the one that can convert
+ // in and out without losing anything with the smallest intermediate length.
+ QTextCodec *best = 0;
+ int shortest = INT_MAX;
+ foreach (QByteArray name, codecs) {
+ QTextCodec* c = QTextCodec::codecForName(name);
+ QString enc = c->toUnicode(ba);
+ if (c->fromUnicode(enc) == ba) {
+ std::cout << QString(c->name()).toStdString() << std::endl;
+ if (enc.length() < shortest) {
+ best = c;
+ shortest = enc.length();
+ }
+ }
+ }
+ return best;
+ } else {
+ return QTextCodec::codecForName(codecs.at(n-1));
+ }
+ }
+
+ static QTextCodec* codecForContent(QByteArray ba, QWidget *parent = 0)
+ {
+ TextCodecSelector tcs(parent);
+ tcs.setModal(true);
+ tcs.exec();
+ if (tcs.result())
+ return tcs.selection(ba);
+ return 0;
+ }
+
+private:
+ QListWidget *list;
+ QList<QByteArray> codecs;
+};
|
|
From: Lasse Kärkkäi. <tr...@us...> - 2011-01-26 01:55:41
|
Module: performous
Branch: stereo3d
Commit: 770202d07ee2252d0399f341bcf8dac28840fb2b
Author: Lasse Karkkainen <tro...@tr...>
Date: Wed Jan 26 02:55:26 2011 +0100
Implement OpenGL matrix/transformation operations in C++ & use them in video_driver.
---
game/glmath.hh | 143 ++++++++++++++++++++++++++++++++++++++++++++++++++
game/glutil.hh | 11 ++--
game/video_driver.cc | 14 +++--
3 files changed, 156 insertions(+), 12 deletions(-)
diff --git a/game/glmath.hh b/game/glmath.hh
new file mode 100644
index 0000000..675a3cf
--- /dev/null
+++ b/game/glmath.hh
@@ -0,0 +1,143 @@
+#pragma once
+
+#include <GL/glew.h>
+#include <cmath>
+#include <iomanip>
+#include <iostream>
+#include <stdexcept>
+#include <sstream>
+
+namespace glmath {
+
+ struct Vec3 {
+ GLdouble x, y, z;
+ explicit Vec3(double x = 0.0, double y = 0.0, double z = 0.0): x(x), y(y), z(z) {}
+ };
+
+ struct Vec4 {
+ GLdouble x, y, z, w;
+ explicit Vec4(double x = 0.0, double y = 0.0, double z = 0.0, double w = 0.0): x(x), y(y), z(z), w(w) {}
+ explicit Vec4(Vec3 const& v, double w = 1.0): x(v.x), y(v.y), z(v.z), w(w) {}
+ GLdouble& operator[](unsigned j) { return (&x)[j]; }
+ GLdouble const& operator[](unsigned j) const { return (&x)[j]; }
+ };
+
+ static inline Vec3 operator*(double k, Vec3 const& v) { return Vec3(k * v.x, k * v.y, k * v.z); }
+
+ static inline double dot(Vec3 const& a, Vec3 const& b) {
+ return a.x * b.x + a.y * b.y + a.z * b.z;
+ }
+
+ static inline double len(Vec3 const& v) { return std::sqrt(dot(v, v)); }
+ static inline Vec3 normalize(Vec3 const& v) { return (1 / len(v)) * v; }
+
+ struct Matrix {
+ Vec4 cols[4];
+ /// Identity matrix
+ Matrix() { for (unsigned k = 0; k < 4; ++k) cols[k][k] = 1.0; }
+ operator GLdouble*() { return &cols[0][0]; }
+ operator GLdouble const*() const { return &cols[0][0]; }
+ GLdouble& operator()(unsigned i, unsigned j) { return cols[j][i]; }
+ GLdouble const& operator()(unsigned i, unsigned j) const { return cols[j][i]; }
+ };
+
+ static inline std::ostream& operator<<(std::ostream& os, Matrix const& m) {
+ std::ostringstream oss;
+ oss << std::setprecision(3) << std::fixed;
+ for (int i = 0; i < 4; ++i) {
+ for (int j = 0; j < 4; ++j) {
+ oss.width(7);
+ oss << m(i,j);
+ }
+ oss << '\n';
+ }
+ return os << oss.str() << std::endl;
+ }
+
+ static inline Matrix get(GLenum mode_matrix) {
+ Matrix ret;
+ glGetDoublev(mode_matrix, ret);
+ return ret;
+ }
+
+ static inline Matrix getMatrix() {
+ GLint mode;
+ glGetIntegerv(GL_MATRIX_MODE, &mode);
+ if (mode == GL_MODELVIEW) return get(GL_MODELVIEW_MATRIX);
+ if (mode == GL_PROJECTION) return get(GL_PROJECTION_MATRIX);
+ if (mode == GL_TEXTURE) return get(GL_TEXTURE_MATRIX);
+ throw std::logic_error("Unknown current matrix mode in glmath::get()");
+ }
+ static inline void upload(Matrix const& m) { glLoadMatrixd(m); }
+
+ static inline Matrix operator*(Matrix const& a, Matrix const& b) {
+ Matrix ret;
+ for (unsigned i = 0; i < 4; ++i) {
+ for (unsigned j = 0; j < 4; ++j) {
+ GLfloat sum = 0.0;
+ for (unsigned k = 0; k < 4; ++k) {
+ sum += a(i, k) * b(k, j);
+ }
+ ret(i, j) = sum;
+ }
+ }
+ return ret;
+ }
+
+ static inline Matrix translate(Vec3 const& v) {
+ Matrix ret;
+ ret(0,3) = v.x;
+ ret(1,3) = v.y;
+ ret(2,3) = v.z;
+ return ret;
+ }
+
+ static inline Matrix scale(Vec3 const& v) {
+ Matrix ret;
+ ret(0,0) = v.x;
+ ret(1,1) = v.y;
+ ret(2,2) = v.z;
+ return ret;
+ }
+
+ static inline Matrix scale(double k) { return scale(Vec3(k, k, k)); }
+
+ static inline Matrix rotate(double rad, Vec3 axis) {
+ Matrix ret;
+ Vec3 u = normalize(axis);
+ // Based on http://en.wikipedia.org/wiki/Rotation_matrix#Rotation_matrix_from_axis_and_angle
+ double s = std::sin(rad);
+ double c = std::cos(rad);
+ double nc = 1 - c;
+ // Column 0
+ ret(0,0) = c + u.x * u.x * nc;
+ ret(1,0) = u.y * u.x * nc + u.z * s;
+ ret(2,0) = u.z * u.x * nc - u.y * s;
+ // Column 1
+ ret(0,1) = u.x * u.y * nc - u.z * s;
+ ret(1,1) = c + u.y * u.y * nc;
+ ret(2,1) = u.z * u.y * nc + u.x * s;
+ // Column 2
+ ret(0,2) = u.x * u.z * nc + u.y * s;
+ ret(1,2) = u.y * u.z * nc - u.x * s;
+ ret(2,2) = c + u.z * u.z * nc;
+ return ret;
+ }
+
+ static inline Matrix frustum(double l, double r, double b, double t, double n, double f) {
+ double w = r - l;
+ double h = t - b;
+ double d = n - f;
+ Matrix ret;
+ ret(0,0) = 2 * n / w;
+ ret(1,1) = 2 * n / h;
+ ret(0,2) = (r + l) / w;
+ ret(1,2) = (t + b) / h;
+ ret(2,2) = (f + n) / d;
+ ret(3,2) = -1.0;
+ ret(2,3) = 2 * f * n / d;
+ ret(3,3) = 0.0;
+ return ret;
+ }
+}
+
diff --git a/game/glutil.hh b/game/glutil.hh
index f25abe1..781b757 100644
--- a/game/glutil.hh
+++ b/game/glutil.hh
@@ -1,13 +1,12 @@
#pragma once
-#include <string>
-#include <iostream>
-#include <vector>
-
-#include <GL/glew.h>
#include "color.hh"
#include "glshader.hh"
+#include <GL/glew.h>
+#include <string>
+#include <iostream>
+#include <vector>
namespace glutil {
@@ -206,6 +205,6 @@ namespace glutil {
}
static void reset() { glGetError(); }
};
-
}
+
diff --git a/game/video_driver.cc b/game/video_driver.cc
index eb505f1..54f677b 100644
--- a/game/video_driver.cc
+++ b/game/video_driver.cc
@@ -2,6 +2,7 @@
#include "config.hh"
#include "fs.hh"
+#include "glmath.hh"
#include "image.hh"
#include "util.hh"
#include "joystick.hh"
@@ -142,19 +143,20 @@ void Window::resize() {
glShadeModel(GL_SMOOTH);
glEnable(GL_BLEND);
// Setup the projection matrix for 2D translates
+ using namespace glmath;
glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
float h = virtH();
// OpenGL normalized coordinates go from -1 to 1, change scale so that our 2D translates can use the Performous normalized coordinates instead
- glScalef(2.0f, 2.0f / h, 1.0f);
+ upload(scale(Vec3(2.0f, 2.0f / h, 1.0f)));
// Note: we do the frustum on MODELVIEW so that 2D positioning can be done via projection matrix.
// glTranslatef on that will move the image, not the camera (i.e. far-away and nearby objects move the same amount)
glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- glScalef(0.5f, 0.5f * h, 1.0f); // Invert the scaling done on projection matrix
const float f = near_ / z0;
- glFrustum(-0.5f * f, 0.5f * f, 0.5f * h * f, -0.5f * h * f, near_, far_);
- glTranslatef(0.0f, 0.0f, -z0); // Move back the world so that z = 0.0f is the monitor surface
+ upload(
+ scale(Vec3(0.5, 0.5 * h, 1.0))
+ * frustum(-0.5f * f, 0.5f * f, 0.5f * h * f, -0.5f * h * f, near_, far_)
+ * translate(Vec3(0.0, 0.0, -z0))
+ );
// Check for OpenGL errors
glutil::GLErrorChecker glerror("Window::resize");
}
|
|
From: Tapio V. <aa...@us...> - 2011-01-25 16:40:13
|
Module: editor
Branch: master
Commit: 604d73f642f318bb4a18b81ada0e8b000e3ec04c
Author: Tapio Vierros <tap...@gm...>
Date: Tue Jan 25 18:39:24 2011 +0200
Dark note graph background gives better contrast.
---
notegraphwidget.cc | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/notegraphwidget.cc b/notegraphwidget.cc
index 7cc2dae..f8c7d9d 100644
--- a/notegraphwidget.cc
+++ b/notegraphwidget.cc
@@ -32,6 +32,9 @@ NoteGraphWidget::NoteGraphWidget(QWidget *parent)
// FIXME: Temporary hack to make testing quicker
analyzeMusic("music.ogg");
+ setProperty("darkBackground", true);
+ setStyleSheet("QLabel[darkBackground=\"true\"] { background: #222; }");
+
setFocusPolicy(Qt::StrongFocus);
setWhatsThis(tr("Note graph that displays the song notes and allows you to manipulate them."));
|
|
From: Lasse Kärkkäi. <tr...@us...> - 2011-01-25 16:04:57
|
Module: editor
Branch: master
Commit: 60164a8f8b9be7be3cb90a8e53518272dbf1c595
Author: Lasse Karkkainen <tro...@tr...>
Date: Tue Jan 25 17:04:24 2011 +0100
Workaround the audio analysis bug (the real fix would go to ffmpeg.*)
---
pitchvis.cc | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/pitchvis.cc b/pitchvis.cc
index d3b1678..64ecae5 100644
--- a/pitchvis.cc
+++ b/pitchvis.cc
@@ -36,15 +36,16 @@ void PitchVis::run()
}
msleep(1000); // Wait some more
setWidth(mpeg.duration() * rate / step); // Estimation
-
curX = 0;
for (std::vector<float> data(step*2); mpeg.audioQueue(&*data.begin(), &*data.end(), curX * step * 2); ++curX) {
+ msleep(2);
// Mix stereo into mono
for (unsigned i = 0; i < step; ++i) data[i] = 0.5 * (data[2*i] + data[2*i + 1]);
// Process
analyzer.input(&data[0], &data[step]);
analyzer.process();
if (cancelled) return;
+ std::fill(data.begin(), data.end(), 0.0f);
}
}
// Draw, TODO: Draw somewhere else (on demand) without a huge bitmap
|
|
From: Lasse Kärkkäi. <tr...@us...> - 2011-01-25 16:04:55
|
Module: editor
Branch: master
Commit: 98a9937d1aef76016408f4e331fcdfe2e59eb9e8
Author: Lasse Karkkainen <tro...@tr...>
Date: Mon Jan 24 17:13:19 2011 +0100
Syntax cleanup
---
pitchvis.hh | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/pitchvis.hh b/pitchvis.hh
index cef0ad5..d01dc5d 100644
--- a/pitchvis.hh
+++ b/pitchvis.hh
@@ -25,10 +25,10 @@ struct Pixel {
}
float& operator[](unsigned idx) { return (&r)[idx]; }
Pixel& operator+=(Pixel const& pix) {
- r = r + pix.r;
- g = g + pix.g;
- b = b + pix.b;
- a = a + pix.a;
+ r += pix.r;
+ g += pix.g;
+ b += pix.b;
+ a += pix.a;
return *this;
}
};
|
|
From: Tapio V. <aa...@us...> - 2011-01-25 14:55:10
|
Module: editor
Branch: master
Commit: 47a7763bc1429bf5c689f03a42c18d6194234006
Author: Tapio Vierros <tap...@gm...>
Date: Tue Jan 25 16:54:08 2011 +0200
Line break visualization updates immediately when toggling checkbox.
---
editorapp.cc | 4 ++--
notegraphwidget.cc | 2 +-
notelabel.hh | 2 ++
3 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/editorapp.cc b/editorapp.cc
index 9e1d822..e0972d4 100644
--- a/editorapp.cc
+++ b/editorapp.cc
@@ -586,8 +586,8 @@ void EditorApp::on_chkFloating_stateChanged(int state)
void EditorApp::on_chkLineBreak_stateChanged(int state)
{
bool linebreak = (state != 0);
- if (noteGraph->selectedNote() && noteGraph->selectedNote()->note().lineBreak != linebreak) {
- noteGraph->selectedNote()->note().lineBreak = linebreak;
+ if (noteGraph->selectedNote() && noteGraph->selectedNote()->isLineBreak() != linebreak) {
+ noteGraph->selectedNote()->setLineBreak(linebreak);
Operation op("LINEBREAK");
op << noteGraph->getNoteLabelId(noteGraph->selectedNote()) << linebreak;
operationDone(op);
diff --git a/notegraphwidget.cc b/notegraphwidget.cc
index 4da17ec..7cc2dae 100644
--- a/notegraphwidget.cc
+++ b/notegraphwidget.cc
@@ -507,7 +507,7 @@ void NoteGraphWidget::doOperation(const Operation& op, Operation::OperationFlags
} else if (action == "FLOATING") {
n->setFloating(op.b(2));
} else if (action == "LINEBREAK") {
- n->note().lineBreak = op.b(2);
+ n->setLineBreak(op.b(2));
} else if (action == "LYRIC") {
n->setLyric(op.s(2));
} else if (action == "TYPE") {
diff --git a/notelabel.hh b/notelabel.hh
index c64a5c6..44c290c 100644
--- a/notelabel.hh
+++ b/notelabel.hh
@@ -30,6 +30,8 @@ public:
bool isFloating() const { return m_floating; }
void setFloating(bool state) { m_floating = state; createPixmap(size()); }
+ bool isLineBreak() const { return m_note.lineBreak; }
+ bool setLineBreak(bool state) { m_note.lineBreak = state; createPixmap(size()); }
void setType(int newtype) { m_note.type = Note::types[newtype]; createPixmap(size()); }
void startResizing(int dir);
|
|
From: Tapio V. <aa...@us...> - 2011-01-25 14:55:08
|
Module: editor
Branch: master
Commit: 8f79c54920409fba4df0cba10e608ce036652852
Author: Tapio Vierros <tap...@gm...>
Date: Tue Jan 25 16:50:45 2011 +0200
Visualize line breaks.
---
notelabel.cc | 7 +++----
1 files changed, 3 insertions(+), 4 deletions(-)
diff --git a/notelabel.cc b/notelabel.cc
index d1503d2..f2ada34 100644
--- a/notelabel.cc
+++ b/notelabel.cc
@@ -65,16 +65,15 @@ void NoteLabel::createPixmap(QSize size)
painter.setRenderHint(QPainter::Antialiasing);
painter.setPen(m_selected ? Qt::red : Qt::black); // Hilight selected note
painter.setBrush(gradient);
- painter.drawRoundedRect(QRectF(0.5, 0.5, image.width()-1, image.height()-1),
- 8, 8);
+ painter.drawRoundedRect(QRectF(0.5, 0.5, image.width()-1, image.height()-1), 8, 8);
painter.setFont(font);
- painter.setBrush(Qt::black);
painter.drawText(QRect(QPoint(text_margin, text_margin), QSize(size.width()-text_margin, size.height()-text_margin)), Qt::AlignCenter, lyric());
// Render sentence end indicator
if (m_note.lineBreak) {
- // TODO
+ painter.setPen(QPen(QBrush(QColor(255, 0, 0)), 4));
+ painter.drawLine(image.width()-2, 0, image.width()-2, image.height()-1);
}
painter.end();
|
|
From: Tapio V. <aa...@us...> - 2011-01-25 14:55:01
|
Module: editor
Branch: master
Commit: db88438d3f6b8d8143c393d4400b528cbd3c7e6d
Author: Tapio Vierros <tap...@gm...>
Date: Tue Jan 25 16:35:22 2011 +0200
Implemented lyrics dumping to file and clipboard.
---
editor.ui | 3 ---
editorapp.cc | 20 +++++++++++++++++++-
editorapp.hh | 2 ++
notegraphwidget.cc | 15 +++++++++++++++
notegraphwidget.hh | 2 ++
5 files changed, 38 insertions(+), 4 deletions(-)
diff --git a/editor.ui b/editor.ui
index 513440e..1dd2b95 100644
--- a/editor.ui
+++ b/editor.ui
@@ -216,9 +216,6 @@
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
- <property name="sizeType">
- <enum>QSizePolicy::Expanding</enum>
- </property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
diff --git a/editorapp.cc b/editorapp.cc
index d51f23c..9e1d822 100644
--- a/editorapp.cc
+++ b/editorapp.cc
@@ -327,7 +327,7 @@ void EditorApp::on_actionUltraStarTXT_triggered()
void EditorApp::on_actionFoFMIDI_triggered()
{
- QString path = QFileDialog::getExistingDirectory(this, tr("Export FoF MIDI"), QDir::homePath());
+ QString path = QFileDialog::getExistingDirectory(this, tr("Export FoF MIDI"), QDir::homePath());
if (!path.isNull()) {
try { FoFMIDIWriter(*song.data(), path); }
catch (const std::exception& e) {
@@ -336,6 +336,24 @@ void EditorApp::on_actionFoFMIDI_triggered()
}
}
+void EditorApp::on_actionLyricsToFile_triggered()
+{
+ QString fileName = QFileDialog::getSaveFileName(this, tr("Export to plain text lyrics"), QDir::homePath());
+ if (!fileName.isNull()) {
+ QFile f(fileName);
+ if (f.open(QFile::WriteOnly | QFile::Truncate)) {
+ QTextStream out(&f);
+ out << noteGraph->dumpLyrics();
+ } else
+ QMessageBox::critical(this, tr("Error saving file!"), tr("Couldn't open file %1 for writing.").arg(fileName));
+ }
+}
+
+void EditorApp::on_actionLyricsToClipboard_triggered()
+{
+ QApplication::clipboard()->setText(noteGraph->dumpLyrics());
+}
+
void EditorApp::on_actionExit_triggered()
{
close();
diff --git a/editorapp.hh b/editorapp.hh
index bbbff64..ee26dd4 100644
--- a/editorapp.hh
+++ b/editorapp.hh
@@ -51,6 +51,8 @@ public slots:
void on_actionSingStarXML_triggered();
void on_actionUltraStarTXT_triggered();
void on_actionFoFMIDI_triggered();
+ void on_actionLyricsToFile_triggered();
+ void on_actionLyricsToClipboard_triggered();
void on_actionExit_triggered();
// Edit menu
diff --git a/notegraphwidget.cc b/notegraphwidget.cc
index 6950fd1..4da17ec 100644
--- a/notegraphwidget.cc
+++ b/notegraphwidget.cc
@@ -531,6 +531,21 @@ int NoteGraphWidget::n2px(int note) const { return m_pitch->note2px(note) - m_no
int NoteGraphWidget::px2n(int px) const { return m_pitch->px2note(px + m_noteHalfHeight); }
+QString NoteGraphWidget::dumpLyrics() const
+{
+ QString lyrics;
+ if (!m_notes.isEmpty()) {
+ for (int i = 0; i < m_notes.size(); ++i) {
+ lyrics += m_notes[i]->lyric() + " ";
+ if (m_notes[i]->note().lineBreak)
+ lyrics.replace(lyrics.size()-1, 1, QString("\n"));
+ }
+ lyrics.replace(lyrics.size()-1, 1, QString("\n"));
+ }
+ return lyrics;
+}
+
+
SeekHandle::SeekHandle(QWidget *parent)
: QLabel(parent)
diff --git a/notegraphwidget.hh b/notegraphwidget.hh
index e2c7e9f..f022495 100644
--- a/notegraphwidget.hh
+++ b/notegraphwidget.hh
@@ -56,6 +56,8 @@ public:
int px2n(int px) const;
int h() const { return m_pitch->height; }
+ QString dumpLyrics() const;
+
public slots:
void timeSyllable();
void timeSentence();
|
|
From: Tapio V. <aa...@us...> - 2011-01-25 14:54:59
|
Module: editor
Branch: master
Commit: 90d15f79de33b7b86e0a7b04e500b5524287d6b3
Author: Tapio Vierros <tap...@gm...>
Date: Tue Jan 25 16:07:47 2011 +0200
Tuning Note properties -tab layout.
---
editor.ui | 68 +++++++++++++++++++++++++++++++++++++-----------------------
1 files changed, 42 insertions(+), 26 deletions(-)
diff --git a/editor.ui b/editor.ui
index 310931e..513440e 100644
--- a/editor.ui
+++ b/editor.ui
@@ -94,7 +94,7 @@
</property>
</widget>
</item>
- <item row="0" column="1">
+ <item row="0" column="2">
<widget class="QLabel" name="valNoteBegin">
<property name="text">
<string>-</string>
@@ -108,14 +108,14 @@
</property>
</widget>
</item>
- <item row="1" column="1">
+ <item row="1" column="2">
<widget class="QLabel" name="valNoteEnd">
<property name="text">
<string>-</string>
</property>
</widget>
</item>
- <item row="0" column="5">
+ <item row="0" column="9">
<widget class="QComboBox" name="cmbNoteType">
<property name="toolTip">
<string>Note type</string>
@@ -143,7 +143,7 @@
</item>
</widget>
</item>
- <item row="1" column="5">
+ <item row="1" column="9">
<widget class="QCheckBox" name="chkFloating">
<property name="layoutDirection">
<enum>Qt::RightToLeft</enum>
@@ -153,61 +153,87 @@
</property>
</widget>
</item>
- <item row="0" column="3">
+ <item row="0" column="7">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Type</string>
</property>
</widget>
</item>
- <item row="2" column="0">
+ <item row="4" column="0">
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="2" column="9">
+ <widget class="QCheckBox" name="chkLineBreak">
+ <property name="layoutDirection">
+ <enum>Qt::RightToLeft</enum>
+ </property>
+ <property name="text">
+ <string>Line break after this</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="4">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Duration</string>
</property>
</widget>
</item>
- <item row="2" column="1">
+ <item row="0" column="5">
<widget class="QLabel" name="valNoteDuration">
<property name="text">
<string>-</string>
</property>
</widget>
</item>
- <item row="3" column="0">
+ <item row="1" column="4">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Note</string>
</property>
</widget>
</item>
- <item row="3" column="1">
+ <item row="1" column="5">
<widget class="QLabel" name="valNote">
<property name="text">
<string>-</string>
</property>
</widget>
</item>
- <item row="4" column="0">
- <spacer name="verticalSpacer">
+ <item row="0" column="6">
+ <spacer name="horizontalSpacer_2">
<property name="orientation">
- <enum>Qt::Vertical</enum>
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
- <width>20</width>
- <height>40</height>
+ <width>40</width>
+ <height>20</height>
</size>
</property>
</spacer>
</item>
- <item row="0" column="2">
+ <item row="0" column="3">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
- <enum>QSizePolicy::Expanding</enum>
+ <enum>QSizePolicy::Maximum</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
@@ -217,16 +243,6 @@
</property>
</spacer>
</item>
- <item row="2" column="5">
- <widget class="QCheckBox" name="chkLineBreak">
- <property name="layoutDirection">
- <enum>Qt::RightToLeft</enum>
- </property>
- <property name="text">
- <string>Line break after this</string>
- </property>
- </widget>
- </item>
</layout>
</widget>
<widget class="QWidget" name="tabSong">
|
|
From: Tapio V. <aa...@us...> - 2011-01-25 13:59:54
|
Module: editor
Branch: master
Commit: a5df16ecc749657c2c4d9333a68f4c9f4630806e
Author: Tapio Vierros <tap...@gm...>
Date: Tue Jan 25 15:59:20 2011 +0200
Make it possible to set line breaks from the UI.
---
editor.ui | 10 ++++++++++
editorapp.cc | 16 +++++++++++++++-
editorapp.hh | 1 +
notegraphwidget.cc | 2 ++
4 files changed, 28 insertions(+), 1 deletions(-)
diff --git a/editor.ui b/editor.ui
index 123ea52..310931e 100644
--- a/editor.ui
+++ b/editor.ui
@@ -217,6 +217,16 @@
</property>
</spacer>
</item>
+ <item row="2" column="5">
+ <widget class="QCheckBox" name="chkLineBreak">
+ <property name="layoutDirection">
+ <enum>Qt::RightToLeft</enum>
+ </property>
+ <property name="text">
+ <string>Line break after this</string>
+ </property>
+ </widget>
+ </item>
</layout>
</widget>
<widget class="QWidget" name="tabSong">
diff --git a/editorapp.cc b/editorapp.cc
index 2a817a7..d51f23c 100644
--- a/editorapp.cc
+++ b/editorapp.cc
@@ -150,6 +150,8 @@ void EditorApp::updateNoteInfo(NoteLabel *note)
ui.cmbNoteType->setCurrentIndex(note->note().getTypeInt());
ui.chkFloating->setEnabled(true);
ui.chkFloating->setChecked(note->isFloating());
+ ui.chkLineBreak->setEnabled(true);
+ ui.chkLineBreak->setChecked(note->note().lineBreak);
} else {
ui.valNoteBegin->setText("-");
ui.valNoteEnd->setText("-");
@@ -157,6 +159,7 @@ void EditorApp::updateNoteInfo(NoteLabel *note)
ui.valNote->setText("-");
ui.cmbNoteType->setEnabled(false);
ui.chkFloating->setEnabled(false);
+ ui.chkLineBreak->setEnabled(false);
}
}
@@ -557,7 +560,18 @@ void EditorApp::on_chkFloating_stateChanged(int state)
if (noteGraph->selectedNote() && noteGraph->selectedNote()->isFloating() != floating) {
noteGraph->selectedNote()->setFloating(floating);
Operation op("FLOATING");
- op << noteGraph->getNoteLabelId(noteGraph->selectedNote()) << (floating);
+ op << noteGraph->getNoteLabelId(noteGraph->selectedNote()) << floating;
+ operationDone(op);
+ }
+}
+
+void EditorApp::on_chkLineBreak_stateChanged(int state)
+{
+ bool linebreak = (state != 0);
+ if (noteGraph->selectedNote() && noteGraph->selectedNote()->note().lineBreak != linebreak) {
+ noteGraph->selectedNote()->note().lineBreak = linebreak;
+ Operation op("LINEBREAK");
+ op << noteGraph->getNoteLabelId(noteGraph->selectedNote()) << linebreak;
operationDone(op);
}
}
diff --git a/editorapp.hh b/editorapp.hh
index d516ab9..bbbff64 100644
--- a/editorapp.hh
+++ b/editorapp.hh
@@ -73,6 +73,7 @@ public slots:
void on_txtYear_editingFinished();
void on_cmbNoteType_currentIndexChanged(int);
void on_chkFloating_stateChanged(int);
+ void on_chkLineBreak_stateChanged(int);
protected:
void closeEvent(QCloseEvent *event);
diff --git a/notegraphwidget.cc b/notegraphwidget.cc
index 73c4c2e..6950fd1 100644
--- a/notegraphwidget.cc
+++ b/notegraphwidget.cc
@@ -506,6 +506,8 @@ void NoteGraphWidget::doOperation(const Operation& op, Operation::OperationFlags
n->setFloating(false);
} else if (action == "FLOATING") {
n->setFloating(op.b(2));
+ } else if (action == "LINEBREAK") {
+ n->note().lineBreak = op.b(2);
} else if (action == "LYRIC") {
n->setLyric(op.s(2));
} else if (action == "TYPE") {
|
|
From: Tapio V. <aa...@us...> - 2011-01-25 13:48:23
|
Module: editor
Branch: master
Commit: 78289f8ecaad76fbf30cbb59bd3d0245aebf19bd
Author: Tapio Vierros <tap...@gm...>
Date: Tue Jan 25 15:47:42 2011 +0200
Ask for saving also on window's X-button click.
---
editorapp.cc | 9 ++++++++-
editorapp.hh | 4 ++++
2 files changed, 12 insertions(+), 1 deletions(-)
diff --git a/editorapp.cc b/editorapp.cc
index 8127f9b..2a817a7 100644
--- a/editorapp.cc
+++ b/editorapp.cc
@@ -6,6 +6,7 @@
#include <QMimeData>
#include <QWhatsThis>
#include <QUrl>
+#include <QCloseEvent>
#include <phonon/AudioOutput>
#include <iostream>
#include "config.hh"
@@ -334,7 +335,7 @@ void EditorApp::on_actionFoFMIDI_triggered()
void EditorApp::on_actionExit_triggered()
{
- if (promptSaving()) close();
+ close();
}
void EditorApp::on_actionUndo_triggered()
@@ -560,3 +561,9 @@ void EditorApp::on_chkFloating_stateChanged(int state)
operationDone(op);
}
}
+
+void EditorApp::closeEvent(QCloseEvent *event)
+{
+ if (promptSaving()) event->accept();
+ else event->ignore();
+}
diff --git a/editorapp.hh b/editorapp.hh
index 2b2172a..d516ab9 100644
--- a/editorapp.hh
+++ b/editorapp.hh
@@ -6,6 +6,7 @@
#include "song.hh"
class QProgressBar;
+class QCloseEvent;
class NoteLabel;
class NoteGraphWidget;
namespace Phonon {
@@ -73,6 +74,9 @@ public slots:
void on_cmbNoteType_currentIndexChanged(int);
void on_chkFloating_stateChanged(int);
+protected:
+ void closeEvent(QCloseEvent *event);
+
private:
Ui::EditorApp ui;
NoteGraphWidget *noteGraph;
|
|
From: Tapio V. <aa...@us...> - 2011-01-25 13:29:24
|
Module: editor
Branch: master
Commit: 56e87680ef773cda9a606741dd1331383e1c494d
Author: Tapio Vierros <tap...@gm...>
Date: Tue Jan 25 15:28:11 2011 +0200
Magic time stamp rounding error compensator for SS XML writer.
Now very good sync.
---
songwriter-xml.cc | 22 +++++++++++++++-------
songwriter.hh | 1 +
2 files changed, 16 insertions(+), 7 deletions(-)
diff --git a/songwriter-xml.cc b/songwriter-xml.cc
index e370e8f..456963e 100644
--- a/songwriter-xml.cc
+++ b/songwriter-xml.cc
@@ -21,26 +21,30 @@ void SingStarXMLWriter::writeXML() {
root.setAttribute("audioVersion", "2"); //?
doc.appendChild(root);
+ // Some helpful comments
QDomComment artistComment = doc.createComment(QString("Artist: ") + s.artist);
QDomComment titleComment = doc.createComment(QString("Title: ") + s.title);
root.appendChild(artistComment);
root.appendChild(titleComment);
+ // Track element
int tracknum = 1;
QDomElement trackElem = doc.createElement("TRACK");
trackElem.setAttribute("Name", "Player1");
trackElem.setAttribute("Artist", s.artist);
root.appendChild(trackElem);
+ // Create first sentence
int sentencenum = 1;
QDomElement sentenceElem = doc.createElement("SENTENCE"); // FIXME: Should there be Singer and Part attributes?
QDomComment sentenceComment = doc.createComment(QString("Track %1, Sentence %2").arg(tracknum).arg(sentencenum));
sentenceElem.appendChild(sentenceComment);
// First sentence also needs a starting SLEEP
Notes const& notes = s.getVocalTrack().notes;
+ int ts = sec2dur(notes.front().begin);
QDomElement firstNoteElem = doc.createElement("NOTE");
firstNoteElem.setAttribute("MidiNote", "0");
- firstNoteElem.setAttribute("Duration", QString::number(sec2dur(notes.front().begin)));
+ firstNoteElem.setAttribute("Duration", QString::number(ts));
firstNoteElem.setAttribute("Lyric", "");
sentenceElem.appendChild(firstNoteElem);
@@ -59,9 +63,10 @@ void SingStarXMLWriter::writeXML() {
} else { // Regular note handling
// Construct the note element
+ int l = sec2dur(n.length()); ts += l;
QDomElement noteElem = doc.createElement("NOTE");
noteElem.setAttribute("MidiNote", QString::number(n.note));
- noteElem.setAttribute("Duration", QString::number(sec2dur(n.length())));
+ noteElem.setAttribute("Duration", QString::number(l));
noteElem.setAttribute("Lyric", n.syllable);
if (n.type == Note::GOLDEN) noteElem.setAttribute("Bonus", "Yes");
if (n.type == Note::FREESTYLE) noteElem.setAttribute("FreeStyle", "Yes");
@@ -70,22 +75,21 @@ void SingStarXMLWriter::writeXML() {
// Construct a note element, indicationg the pause before next note
// This is only done if the pause has duration
+ // We also take the overall position into consideration (counter rounding errors)
int pauseLen = 0;
+ double end = dur2sec(ts) + n.length();
if (i < notes.size() - 1)
- pauseLen = sec2dur(notes[i+1].begin - n.end); // Difference to next note
+ pauseLen = sec2dur(notes[i+1].begin - end); // Difference to next note
if (pauseLen > 0) {
QDomElement pauseElem = doc.createElement("NOTE");
pauseElem.setAttribute("MidiNote", "0");
pauseElem.setAttribute("Duration", QString::number(pauseLen));
pauseElem.setAttribute("Lyric", "");
sentenceElem.appendChild(pauseElem);
+ ts += pauseLen;
}
}
- // TODO: Needs a last dummy sentence
-
- //root.appendChild(sentenceElem);
-
// Get the xml data
QString xml = doc.toString(4);
// Write to file
@@ -99,3 +103,7 @@ void SingStarXMLWriter::writeXML() {
int SingStarXMLWriter::sec2dur(double sec) {
return round(tempo / 60.0 * sec * 8); // 8 for Demisemiquaver
}
+
+double SingStarXMLWriter::dur2sec(int ts) {
+ return ts * 60.0 / (tempo * 8); // 8 for Demisemiquaver
+}
diff --git a/songwriter.hh b/songwriter.hh
index 13016fb..fe21997 100644
--- a/songwriter.hh
+++ b/songwriter.hh
@@ -17,6 +17,7 @@ struct SingStarXMLWriter: public SongWriter
private:
void writeXML();
int sec2dur(double sec);
+ double dur2sec(int ts);
int tempo;
};
|
|
From: Tapio V. <aa...@us...> - 2011-01-25 10:24:09
|
Module: editor
Branch: master
Commit: 5541dec56580d545e936988d3044e06d461557e2
Author: Tapio Vierros <tap...@gm...>
Date: Tue Jan 25 12:22:50 2011 +0200
Remove dependency to boost::regex and boost::filesystem.
---
CMakeLists.txt | 2 +-
songparser.cc | 25 +------------------------
2 files changed, 2 insertions(+), 25 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 714c48e..5a286f4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -24,7 +24,7 @@ foreach(lib AVFormat SWScale)
add_definitions(${${lib}_DEFINITIONS})
endforeach(lib)
-find_package(Boost 1.36 REQUIRED COMPONENTS thread regex filesystem system)
+find_package(Boost 1.36 REQUIRED COMPONENTS thread)
include_directories(${Boost_INCLUDE_DIRS})
list(APPEND LIBS ${Boost_LIBRARIES})
diff --git a/songparser.cc b/songparser.cc
index 708c2e6..bf2bc9b 100644
--- a/songparser.cc
+++ b/songparser.cc
@@ -2,8 +2,6 @@
#include <QFile>
#include <QFileInfo>
-#include <boost/regex.hpp>
-#include <boost/filesystem.hpp>
namespace SongParserUtil {
@@ -68,29 +66,8 @@ SongParser::SongParser(Song& s):
if (!QFileInfo(m_song.path + m_song.background).exists()) m_song.background = "";
if (!QFileInfo(m_song.path + m_song.video).exists()) m_song.video = "";
- // In case no images/videos were specified, try to guess them
- try {
- if (m_song.cover.isEmpty() || m_song.background.isEmpty() || m_song.video.isEmpty()) {
- boost::regex coverfile("((cover|album|label|\\[co\\])\\.(png|jpeg|jpg|svg))$", boost::regex_constants::icase);
- boost::regex backgroundfile("((background|bg||\\[bg\\])\\.(png|jpeg|jpg|svg))$", boost::regex_constants::icase);
- boost::regex videofile("(.*\\.(avi|mpg|mpeg|flv|mov|mp4))$", boost::regex_constants::icase);
- boost::cmatch match;
-
- for (boost::filesystem::directory_iterator dirIt(s.path.toStdString()), dirEnd; dirIt != dirEnd; ++dirIt) {
- boost::filesystem::path p = dirIt->path();
- std::string name = p.leaf(); // File basename
- if (m_song.cover.isEmpty() && regex_match(name.c_str(), match, coverfile)) {
- m_song.cover = QString::fromStdString(name);
- } else if (m_song.background.isEmpty() && regex_match(name.c_str(), match, backgroundfile)) {
- m_song.background = QString::fromStdString(name);
- } else if (m_song.video.isEmpty() && regex_match(name.c_str(), match, videofile)) {
- m_song.video = QString::fromStdString(name);
- }
- }
- }
- } catch (...) {
- // FIXME: Due to conversion errors, directory_iterator may fail - reimplement with Qt
- }
+ // TODO: Should we try to guess images and stuff?
+
finalize(); // Do some adjusting to the notes
s.loadStatus = Song::FULL;
}
|
|
From: Tapio V. <aa...@us...> - 2011-01-25 10:24:07
|
Module: editor Branch: master Commit: c139cff5312d58124bbb5755ec5568805a4b1bcd Author: Tapio Vierros <tap...@gm...> Date: Tue Jan 25 12:19:56 2011 +0200 Some clean-up left over from previous commit. --- songparser-txt.cc | 8 +-- songparser-xml.cc | 227 ----------------------------------------------------- songparser.cc | 3 - 3 files changed, 1 insertions(+), 237 deletions(-) |
|
From: Tapio V. <aa...@us...> - 2011-01-25 10:24:04
|
Module: editor Branch: master Commit: d43a7a7ad327ac6fb27be3c4567c3a6d02869047 Author: Tapio Vierros <tap...@gm...> Date: Tue Jan 25 12:10:19 2011 +0200 Massive QTfication. * Almost all std::strings replaced by QStrings. * Files can now be loaded from non-ascii paths. * No codec auto-detection yet (so some lyrics may be b0rked). * SongParser, including TXT, now uses Qt's I/O stuff. --- editorapp.cc | 36 +++++++------- notegraphwidget.cc | 6 +- notelabel.cc | 4 +- notelabel.hh | 4 +- notes.cc | 19 ++++--- notes.hh | 15 +++--- song.cc | 6 ++- song.hh | 88 ++++++++++++++++--------------- songparser-txt.cc | 92 +++++++++++++++++---------------- songparser-xml.cc | 23 +++------ songparser.cc | 145 +++++++++++++++++++++++----------------------------- songparser.hh | 30 ++++------- songwriter-ini.cc | 2 +- songwriter-xml.cc | 12 ++-- 14 files changed, 227 insertions(+), 255 deletions(-) |
|
From: Tapio V. <aa...@us...> - 2011-01-25 07:34:17
|
Module: editor
Branch: master
Commit: d79b2063a627f354d3b7d278fbee98d3617e1493
Author: Tapio Vierros <tap...@gm...>
Date: Tue Jan 25 09:32:14 2011 +0200
Initial "timing during playback" implementation.
Weight on the word initial.
---
editor.ui | 57 ++++++++++++++++++++++++++++++++++++++++++++++-
editorapp.cc | 2 +
notegraphwidget.cc | 62 ++++++++++++++++++++++++++++++++++++++++++++++++---
notegraphwidget.hh | 8 ++++++
4 files changed, 123 insertions(+), 6 deletions(-)
diff --git a/editor.ui b/editor.ui
index b579695..123ea52 100644
--- a/editor.ui
+++ b/editor.ui
@@ -321,16 +321,43 @@
</attribute>
<layout class="QGridLayout" name="gridLayout_6">
<item row="0" column="0">
+ <widget class="QLabel" name="label_11">
+ <property name="text">
+ <string>Playback</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLabel" name="label_12">
+ <property name="text">
+ <string>Timing</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
<widget class="QPushButton" name="cmdPlay">
<property name="toolTip">
- <string>Start playing the music file.</string>
+ <string>Play/pause the music file.</string>
</property>
<property name="text">
<string>Play</string>
</property>
</widget>
</item>
- <item row="0" column="1">
+ <item row="1" column="1">
+ <widget class="QPushButton" name="cmdTimeSyllable">
+ <property name="toolTip">
+ <string>Set selected note start to cursor position.</string>
+ </property>
+ <property name="text">
+ <string>Time syllable (N)</string>
+ </property>
+ <property name="shortcut">
+ <string>N</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
<widget class="QPushButton" name="cmdStop">
<property name="toolTip">
<string>Stop the music.</string>
@@ -340,6 +367,32 @@
</property>
</widget>
</item>
+ <item row="2" column="1">
+ <widget class="QPushButton" name="cmdTimeSentence">
+ <property name="toolTip">
+ <string>Set selected note start to cursor position and move to next sentence start.</string>
+ </property>
+ <property name="text">
+ <string>Time sentence (M)</string>
+ </property>
+ <property name="shortcut">
+ <string>M</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <spacer name="verticalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
</layout>
</widget>
</widget>
diff --git a/editorapp.cc b/editorapp.cc
index 0489304..856a1ad 100644
--- a/editorapp.cc
+++ b/editorapp.cc
@@ -36,6 +36,8 @@ EditorApp::EditorApp(QWidget *parent): QMainWindow(parent), projectFileName(), h
// Custom signals/slots
connect(noteGraph, SIGNAL(operationDone(const Operation&)), this, SLOT(operationDone(const Operation&)));
connect(noteGraph, SIGNAL(updateNoteInfo(NoteLabel*)), this, SLOT(updateNoteInfo(NoteLabel*)));
+ connect(ui.cmdTimeSyllable, SIGNAL(pressed()), noteGraph, SLOT(timeSyllable()));
+ connect(ui.cmdTimeSentence, SIGNAL(pressed()), noteGraph, SLOT(timeSentence()));
// Duplicate/reused signals/slots
connect(ui.cmdMusicFile, SIGNAL(clicked()), this, SLOT(on_actionMusicFile_triggered()));
diff --git a/notegraphwidget.cc b/notegraphwidget.cc
index d3e4a4c..689d772 100644
--- a/notegraphwidget.cc
+++ b/notegraphwidget.cc
@@ -213,6 +213,58 @@ void NoteGraphWidget::seek(int x)
emit seeked(1000 * px2s(x));
}
+void NoteGraphWidget::timeCurrent()
+{
+ if (m_selectedNote) {
+ // TODO: Automatic pitch detection
+ Operation op("MOVE");
+ op << getNoteLabelId(m_selectedNote)
+ << m_seekHandle.curx() << m_selectedNote->y();
+ doOperation(op);
+ }
+}
+
+void NoteGraphWidget::timeSyllable()
+{
+ timeCurrent();
+ selectNextSyllableAfterSeekHandle();
+}
+
+void NoteGraphWidget::timeSentence()
+{
+ timeCurrent();
+ selectNextSentenceStart();
+}
+
+void NoteGraphWidget::selectNextSyllableAfterSeekHandle()
+{
+ bool currentFound = (m_selectedNote ? false : true);
+ if (m_notes.size() > 1 && m_selectedNote != m_notes.back()) {
+ for (NoteLabels::iterator it = m_notes.begin(); it != m_notes.end(); ++it) {
+ if (m_selectedNote == *it) currentFound = true;
+ else if (currentFound && (*it)->x() > m_seekHandle.curx()) {
+ selectNote(*it); break;
+ }
+ }
+ }
+}
+
+void NoteGraphWidget::selectNextSentenceStart()
+{
+ bool currentFound = (m_selectedNote ? false : true);
+ NoteLabel *prev = NULL;
+ if (m_notes.size() > 1 && m_selectedNote != m_notes.back()) {
+ for (NoteLabels::iterator it = m_notes.begin(); it != m_notes.end(); prev = *it, ++it) {
+ if (m_selectedNote == *it) currentFound = true;
+ else if (currentFound && (*it)->x() > m_seekHandle.curx()
+ && prev && prev->note().lineBreak) {
+ selectNote(*it); break;
+ }
+ }
+ }
+}
+
+
void NoteGraphWidget::mousePressEvent(QMouseEvent *event)
{
NoteLabel *child = qobject_cast<NoteLabel*>(childAt(event->pos()));
@@ -313,6 +365,7 @@ void NoteGraphWidget::mouseDoubleClickEvent(QMouseEvent *event)
if (!child) {
// Double click empty space = seek there
seek(event->x());
+ selectNextSyllableAfterSeekHandle();
return;
}
@@ -342,8 +395,8 @@ void NoteGraphWidget::mouseMoveEvent(QMouseEvent *event)
m_actionHappened = true; // We have movement, so resize/move can be accepted
// See if the note needs to be unfloated
if (m_selectedAction != NONE && m_selectedNote && m_selectedNote->isFloating()) {
- Operation op("FLOATING"); op << getNoteLabelId(m_selectedNote) << false;
- doOperation(op);
+ // Undo op is handled later by the SETGEOM constructed at drop
+ m_selectedNote->setFloating(false);
}
}
@@ -442,14 +495,15 @@ void NoteGraphWidget::doOperation(const Operation& op, Operation::OperationFlags
if (action == "DEL") {
n->close();
m_notes.removeAt(op.i(1));
- } else if (action == "SPLIT") {
- // TODO
} else if (action == "SETGEOM") {
n->setGeometry(op.i(2), op.i(3), op.i(4), op.i(5));
+ n->setFloating(false);
} else if (action == "RESIZE") {
n->resize(op.i(2), op.i(3));
+ n->setFloating(false);
} else if (action == "MOVE") {
n->move(op.i(2), op.i(3));
+ n->setFloating(false);
} else if (action == "FLOATING") {
n->setFloating(op.b(2));
} else if (action == "LYRIC") {
diff --git a/notegraphwidget.hh b/notegraphwidget.hh
index 3db1520..e2c7e9f 100644
--- a/notegraphwidget.hh
+++ b/notegraphwidget.hh
@@ -16,6 +16,7 @@ class SeekHandle: public QLabel
Q_OBJECT
public:
SeekHandle(QWidget *parent = 0);
+ int curx() const { return x() + width() / 2; }
int moveTimerId;
protected:
void mouseMoveEvent(QMouseEvent *event);
@@ -55,6 +56,10 @@ public:
int px2n(int px) const;
int h() const { return m_pitch->height; }
+public slots:
+ void timeSyllable();
+ void timeSentence();
+
signals:
void updateNoteInfo(NoteLabel*);
void analyzeProgress(int, int);
@@ -72,6 +77,9 @@ protected:
private:
void finalizeNewLyrics();
+ void timeCurrent();
+ void selectNextSyllableAfterSeekHandle();
+ void selectNextSentenceStart();
int m_requiredWidth;
int m_noteHalfHeight;
|
|
From: Tapio V. <aa...@us...> - 2011-01-25 07:34:14
|
Module: editor
Branch: master
Commit: 46c26a024e19115cf9c6c362a718fdee7f994096
Author: Tapio Vierros <tap...@gm...>
Date: Tue Jan 25 08:34:36 2011 +0200
Three dots to menu captions that need it.
---
editor.ui | 19 +++++++++++--------
1 files changed, 11 insertions(+), 8 deletions(-)
diff --git a/editor.ui b/editor.ui
index b7872c6..b579695 100644
--- a/editor.ui
+++ b/editor.ui
@@ -418,7 +418,7 @@
<widget class="QStatusBar" name="statusbar"/>
<action name="actionAbout">
<property name="text">
- <string>&About</string>
+ <string>&About...</string>
</property>
</action>
<action name="actionNew">
@@ -431,7 +431,7 @@
</action>
<action name="actionOpen">
<property name="text">
- <string>&Open</string>
+ <string>&Open...</string>
</property>
<property name="shortcut">
<string>Ctrl+O</string>
@@ -481,18 +481,21 @@
</property>
</action>
<action name="actionPreferences">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
<property name="text">
<string>&Preferences</string>
</property>
</action>
<action name="actionSingStarXML">
<property name="text">
- <string>&SingStar XML</string>
+ <string>&SingStar XML...</string>
</property>
</action>
<action name="actionLyricsToFile">
<property name="text">
- <string>Lyrics to fi&le</string>
+ <string>Lyrics to fi&le...</string>
</property>
</action>
<action name="actionLyricsToClipboard">
@@ -502,12 +505,12 @@
</action>
<action name="actionMusicFile">
<property name="text">
- <string>&Music file</string>
+ <string>&Music file...</string>
</property>
</action>
<action name="actionLyricsFromFile">
<property name="text">
- <string>Lyrics from fi&le</string>
+ <string>Lyrics from fi&le...</string>
</property>
</action>
<action name="actionLyricsFromClipboard">
@@ -517,12 +520,12 @@
</action>
<action name="actionUltraStarTXT">
<property name="text">
- <string>&UltraStar TXT</string>
+ <string>&UltraStar TXT...</string>
</property>
</action>
<action name="actionFoFMIDI">
<property name="text">
- <string>&FoF MIDI</string>
+ <string>&FoF MIDI...</string>
</property>
</action>
<action name="actionWhatsThis">
|
|
From: Tapio V. <aa...@us...> - 2011-01-24 19:37:10
|
Module: editor
Branch: master
Commit: 93a7787b0dbb2fee540825367eb8e22976c2296f
Author: Tapio Vierros <tap...@gm...>
Date: Mon Jan 24 21:33:30 2011 +0200
SS XML writer fix: Much better sync due to improved SLEEP handling.
---
songwriter-xml.cc | 24 ++++++++++++------------
1 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/songwriter-xml.cc b/songwriter-xml.cc
index 57ec88e..694a43a 100644
--- a/songwriter-xml.cc
+++ b/songwriter-xml.cc
@@ -66,19 +66,19 @@ void SingStarXMLWriter::writeXML() {
if (n.type == Note::GOLDEN) noteElem.setAttribute("Bonus", "Yes");
if (n.type == Note::FREESTYLE) noteElem.setAttribute("FreeStyle", "Yes");
sentenceElem.appendChild(noteElem);
+ }
- // Construct a second note element, indicationg the pause before next note
- // This is only done if the pause has duration
- int pauseLen = 0;
- if (i < notes.size() - 1)
- pauseLen = sec2dur(notes[i+1].begin - n.end); // Difference to next note
- if (pauseLen > 0) {
- QDomElement pauseElem = doc.createElement("NOTE");
- pauseElem.setAttribute("MidiNote", "0");
- pauseElem.setAttribute("Duration", QString::number(pauseLen));
- pauseElem.setAttribute("Lyric", "");
- sentenceElem.appendChild(pauseElem);
- }
+ // Construct a note element, indicationg the pause before next note
+ // This is only done if the pause has duration
+ int pauseLen = 0;
+ if (i < notes.size() - 1)
+ pauseLen = sec2dur(notes[i+1].begin - n.end); // Difference to next note
+ if (pauseLen > 0) {
+ QDomElement pauseElem = doc.createElement("NOTE");
+ pauseElem.setAttribute("MidiNote", "0");
+ pauseElem.setAttribute("Duration", QString::number(pauseLen));
+ pauseElem.setAttribute("Lyric", "");
+ sentenceElem.appendChild(pauseElem);
}
}
|
|
From: Tapio V. <aa...@us...> - 2011-01-24 17:24:53
|
Module: editor
Branch: master
Commit: 7b746d3d546b95055efe63bb8984117367ac8d58
Author: Tapio Vierros <tap...@gm...>
Date: Mon Jan 24 19:23:17 2011 +0200
SS XML writer fixes - still some issues, but getting there.
---
songwriter-xml.cc | 12 +++++++++---
1 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/songwriter-xml.cc b/songwriter-xml.cc
index e114f8f..57ec88e 100644
--- a/songwriter-xml.cc
+++ b/songwriter-xml.cc
@@ -36,9 +36,15 @@ void SingStarXMLWriter::writeXML() {
QDomElement sentenceElem = doc.createElement("SENTENCE"); // FIXME: Should there be Singer and Part attributes?
QDomComment sentenceComment = doc.createComment(QString("Track %1, Sentence %2").arg(tracknum).arg(sentencenum));
sentenceElem.appendChild(sentenceComment);
+ // First sentence also needs a starting SLEEP
+ Notes const& notes = s.getVocalTrack().notes;
+ QDomElement firstNoteElem = doc.createElement("NOTE");
+ firstNoteElem.setAttribute("MidiNote", "0");
+ firstNoteElem.setAttribute("Duration", QString::number(sec2dur(notes.front().begin)));
+ firstNoteElem.setAttribute("Lyric", "");
+ sentenceElem.appendChild(firstNoteElem);
// Iterate all notes
- Notes const& notes = s.getVocalTrack().notes;
for (unsigned int i = 0; i < notes.size(); ++i) {
Note const& n = notes[i];
@@ -69,7 +75,7 @@ void SingStarXMLWriter::writeXML() {
if (pauseLen > 0) {
QDomElement pauseElem = doc.createElement("NOTE");
pauseElem.setAttribute("MidiNote", "0");
- pauseElem.setAttribute("Duration", QString::number(sec2dur(pauseLen)));
+ pauseElem.setAttribute("Duration", QString::number(pauseLen));
pauseElem.setAttribute("Lyric", "");
sentenceElem.appendChild(pauseElem);
}
@@ -78,7 +84,7 @@ void SingStarXMLWriter::writeXML() {
// TODO: Needs a last dummy sentence
- root.appendChild(sentenceElem);
+ //root.appendChild(sentenceElem);
// Get the xml data
QString xml = doc.toString(4);
|
|
From: Tapio V. <aa...@us...> - 2011-01-24 17:24:50
|
Module: editor Branch: master Commit: 94becf34f8c646ea5558876b098cf146c8b06714 Author: Tapio Vierros <tap...@gm...> Date: Mon Jan 24 19:00:07 2011 +0200 Document file format support. --- docs/FileFormats.txt | 35 +++++++++++++++++++++++++++++++++++ 1 files changed, 35 insertions(+), 0 deletions(-) diff --git a/docs/FileFormats.txt b/docs/FileFormats.txt new file mode 100644 index 0000000..d9f8a3d --- /dev/null +++ b/docs/FileFormats.txt @@ -0,0 +1,35 @@ +Editor file format support +========================== + +This document describes to what extent various file formats are supported by the editor. + + +Own project files +----------------- +Native save/load format. Preserves operation history (undo buffer). Currently only saves notes, not metadata. + + +SingStar XML +------------ +Import and export. Round-trip is not perfect: All XML elements except MELODY, TRACK, SENTENCE and NOTE are ignored as are all attributes of SENTENCE-element. Exporter writes some useful comments. + + +UltraStar TXT +------------- +Import only, export planned. + + +Frets on Fire MIDI/INI +---------------------- +No support, but both import and export are planned. + + +Plain text lyrics +----------------- +Raw lyrics without any timing data can be read from a file or copied from clipboard. A note is created for each word and a line break indicates sentence end. + + +Music files +----------- +The pitch analysis can be performed to any file that FFmpeg can decode. Playback and metadata reading support depends on Phonon media library back-end. + |