From 6031ac2af145a8aaf95663acd612f65b09483cac Mon Sep 17 00:00:00 2001 From: Werner Schweer Date: Thu, 11 May 2006 15:34:18 +0000 Subject: updates to project handling --- muse/ChangeLog | 2 + muse/awl/tcanvas.cpp | 3 +- muse/muse/audioaux.cpp | 2 +- muse/muse/audiooutput.cpp | 2 +- muse/muse/exportmidi.cpp | 2 +- muse/muse/muse.cpp | 53 ++++----- muse/muse/muse.qrc | 1 + muse/muse/preferences.cpp | 1 + muse/muse/projectdialog.cpp | 205 +++++++++++++++++++++++++++++--- muse/muse/projectdialog.h | 11 +- muse/muse/projectdialog.ui | 256 ++++++++++++++++++++++++---------------- muse/muse/song.cpp | 26 ++-- muse/muse/song.h | 7 +- muse/muse/wave.cpp | 4 +- muse/muse/waveedit/waveview.cpp | 4 +- muse/muse/xpm/folder_new.png | Bin 0 -> 1278 bytes 16 files changed, 415 insertions(+), 164 deletions(-) create mode 100644 muse/muse/xpm/folder_new.png diff --git a/muse/ChangeLog b/muse/ChangeLog index 5a4379e3..33b4639a 100644 --- a/muse/ChangeLog +++ b/muse/ChangeLog @@ -1,3 +1,5 @@ +11.5 (ws) + * implemented new project handling; first docs in doc/man/de 3.5 (ws) * moved build system to cmake * moved repository to svn diff --git a/muse/awl/tcanvas.cpp b/muse/awl/tcanvas.cpp index 0fe29e28..8b9a0925 100644 --- a/muse/awl/tcanvas.cpp +++ b/muse/awl/tcanvas.cpp @@ -678,10 +678,11 @@ void TimeCanvas::paintMetronomRuler(QPainter& p, const QRect& r) pos2.mbt(&bar2, &beat, &tick); int n = mag[metronomeRulerMag]; + bar1 = (bar1 / n) * n; // round down if (bar1 && n >= 2) bar1 -= 1; - bar2 = ((bar2 + n - 1) / n) * n - 1; // round up + bar2 = ((bar2 + n - 1) / n) * n; // round up for (int bar = bar1; bar <= bar2;) { AL::Pos stick(bar, 0, 0); diff --git a/muse/muse/audioaux.cpp b/muse/muse/audioaux.cpp index 1f1903f4..9023f058 100644 --- a/muse/muse/audioaux.cpp +++ b/muse/muse/audioaux.cpp @@ -90,7 +90,7 @@ void AudioAux::collectInputData() break; } } - RouteList* rl = inRoutes(); +// RouteList* rl = inRoutes(); bool copy = true; TrackList* tl = song->tracks(); diff --git a/muse/muse/audiooutput.cpp b/muse/muse/audiooutput.cpp index fbaac33c..b6cd4d70 100644 --- a/muse/muse/audiooutput.cpp +++ b/muse/muse/audiooutput.cpp @@ -178,7 +178,7 @@ void AudioOutput::deactivate() // gui context //--------------------------------------------------------- -void AudioOutput::stopRecording(const Pos& s, const Pos& e) +void AudioOutput::stopRecording(const Pos& /*s*/, const Pos& /*e*/) { SndFile* sf = recFile(); if (sf) diff --git a/muse/muse/exportmidi.cpp b/muse/muse/exportmidi.cpp index 1cfff45e..879482f4 100644 --- a/muse/muse/exportmidi.cpp +++ b/muse/muse/exportmidi.cpp @@ -116,7 +116,7 @@ static void addController(MPEventList* l, int tick, int /*port*/, int channel, i void MusE::exportMidi() { if (exportMidiDialog == 0) - exportMidiDialog = new ExportMidiDialog(song->projectDirectory()); + exportMidiDialog = new ExportMidiDialog(song->projectPath()); int rv = exportMidiDialog->exec(); if (rv == 0) return; diff --git a/muse/muse/muse.cpp b/muse/muse/muse.cpp index ea454a9a..26da3c8c 100644 --- a/muse/muse/muse.cpp +++ b/muse/muse/muse.cpp @@ -308,9 +308,8 @@ bool MusE::seqRestart() // addProject //--------------------------------------------------------- -void addProject(const QFileInfo& f) +void addProject(const QString& name) { - QString name(f.absoluteFilePath()); for (int i = 0; i < PROJECT_LIST_LEN; ++i) { if (projectList[i] == 0) break; @@ -1039,7 +1038,7 @@ void MusE::localOff() // loadProject //--------------------------------------------------------- -void MusE::loadProject(const QString& name) +void MusE::loadProject(const QString& path) { // // stop audio threads if running @@ -1053,7 +1052,7 @@ void MusE::loadProject(const QString& name) } seqStop(); } - loadProject1(name); + loadProject1(path); if (restartSequencer) seqStart(); audio->msgSeek(song->cPos()); @@ -1063,15 +1062,17 @@ void MusE::loadProject(const QString& name) // loadProject1 //--------------------------------------------------------- -void MusE::loadProject1(const QString& name) +void MusE::loadProject1(const QString& path) { + QString header(tr("MusE: new project")); + if (mixer1) mixer1->clear(); if (mixer2) mixer2->clear(); if (song->dirty) { int n = 0; - n = QMessageBox::warning(this, appName, + n = QMessageBox::warning(this, header, tr("The current Project contains unsaved data\n" "Load overwrites current Project:\n" "Save Current Project?"), @@ -1089,14 +1090,17 @@ void MusE::loadProject1(const QString& name) printf("InternalError: gibt %d\n", n); } } + QString name = path.split("/").last(); + QDir pd(QDir::homePath() + "/" + config.projectPath + "/" + path); + + addProject(path); // add to history - QDir pd(QDir::homePath() + "/" + config.projectPath + "/" + name); bool newProject = false; if (!pd.exists()) { newProject = true; if (!pd.mkdir(pd.path())) { - QMessageBox::critical(this, QString("MusE: new project"), - tr("Cannot create project directory")); + QString s(tr("Cannot create project folder <%1>")); + QMessageBox::critical(this, header, s.arg(pd.path())); return; } } @@ -1115,7 +1119,7 @@ void MusE::loadProject1(const QString& name) w->close(); } emit startLoadSong(); - song->setProjectName(name); + song->setProjectPath(path); song->load(); tr_id->setChecked(config.transportVisible); @@ -1190,10 +1194,10 @@ void MusE::loadProject() int rv = projectDialog.exec(); if (rv == 0) return; - QString name = projectDialog.project(); - if (name.isEmpty()) + QString path = projectDialog.projectPath(); + if (path.isEmpty()) return; - loadProject(name); + loadProject(path); } //--------------------------------------------------------- @@ -1205,7 +1209,7 @@ bool MusE::save() QString backupCommand; QString name(song->projectName() + ".med"); - QFileInfo fi(song->projectDirectory() + "/" + name); + QFileInfo fi(song->absoluteProjectPath() + "/" + name); QTemporaryFile tmp(fi.path() + "/MusEXXXXXX"); tmp.setAutoRemove(false); @@ -2881,20 +2885,17 @@ int main(int argc, char* argv[]) } } - QString name; + QString path; // project path relativ to config.projectPath if (argc >= 2) - name = argv[optind]; // start with first name on command line + path = argv[optind]; // start with first name on command line else if (config.startMode == START_LAST_PROJECT) { if (projectList[0]) - name = *projectList[0]; + path = *projectList[0]; } else if (config.startMode == START_START_PROJECT) - name = config.startProject; + path = config.startProject; - //DEBUG: - name = ""; - - if (name.isEmpty()) { + if (path.isEmpty()) { // // ask user for a project // @@ -2902,8 +2903,8 @@ int main(int argc, char* argv[]) ProjectDialog projectDialog; int rv = projectDialog.exec(); if (rv == 1) { - name = projectDialog.project(); - if (!name.isEmpty()) + path = projectDialog.projectPath(); + if (!path.isEmpty()) break; } // the user did not select/create a project @@ -2922,7 +2923,7 @@ int main(int argc, char* argv[]) } } - muse->loadProject(name); + muse->loadProject(path); muse->changeConfig(false); if (!debugMode) { @@ -2936,5 +2937,3 @@ int main(int argc, char* argv[]) fprintf(stderr, "app end %d\n", n); return n; } - - diff --git a/muse/muse/muse.qrc b/muse/muse/muse.qrc index b5132647..e37e035e 100644 --- a/muse/muse/muse.qrc +++ b/muse/muse/muse.qrc @@ -14,6 +14,7 @@ xpm/play.xpm xpm/frewind.xpm xpm/fforward.xpm + xpm/folder_new.png diff --git a/muse/muse/preferences.cpp b/muse/muse/preferences.cpp index 96054b4a..f8b838cd 100644 --- a/muse/muse/preferences.cpp +++ b/muse/muse/preferences.cpp @@ -340,6 +340,7 @@ PreferencesDialog::PreferencesDialog(Arranger* a, QWidget* parent) setTransportCurrent->setEnabled(muse->transportWindow()); freewheelMode->setChecked(config->useJackFreewheelMode); showSplash->setChecked(config->showSplashScreen); + projectPath->setText(config->projectPath); stopActive->setChecked(midiRCList.isActive(RC_STOP)); playActive->setChecked(midiRCList.isActive(RC_PLAY)); diff --git a/muse/muse/projectdialog.cpp b/muse/muse/projectdialog.cpp index 95108be1..ffd039f2 100644 --- a/muse/muse/projectdialog.cpp +++ b/muse/muse/projectdialog.cpp @@ -21,6 +21,39 @@ #include "projectdialog.h" #include "gconfig.h" #include "song.h" +#include "icons.h" + +// +// entry types for projectTree tree widget: +// +enum { DIR_TYPE, PROJECT_TYPE }; + +//--------------------------------------------------------- +// processSubdirectories +//--------------------------------------------------------- + +void ProjectDialog::processSubdir(QTreeWidgetItem* item, const QString& p, + const QString& subdir, QTreeWidgetItem** current) + { + QString path(p + "/" + subdir); + QFile pf(path + "/" + subdir + ".med"); + if (pf.exists()) { + QTreeWidgetItem* pi = new QTreeWidgetItem(item, PROJECT_TYPE); + pi->setText(0, subdir); + pi->setIcon(0, style()->standardIcon(QStyle::SP_FileIcon)); + if (path == song->absoluteProjectPath()) + *current = pi; + } + else { + QDir sd(path); + QStringList dl = sd.entryList(QDir::AllDirs | QDir::NoDotAndDotDot); + QTreeWidgetItem* pi = new QTreeWidgetItem(item, DIR_TYPE); + pi->setText(0, subdir); + itemCollapsed(pi); + foreach (QString s, dl) + processSubdir(pi, path, s, current); + } + } //--------------------------------------------------------- // ProjectDialog @@ -36,50 +69,114 @@ ProjectDialog::ProjectDialog(QWidget* parent) QStringList el = pd.entryList(QDir::AllDirs | QDir::NoDotAndDotDot); QTreeWidgetItem* current = 0; foreach (QString s, el) { - QFile pf(QDir::homePath() + "/" + config.projectPath + "/" - + s + "/" + s + ".med"); + QString path(QDir::homePath() + "/" + config.projectPath + "/" + s); + QFile pf(path + "/" + s + ".med"); if (pf.exists()) { - QTreeWidgetItem* pi = new QTreeWidgetItem; + QTreeWidgetItem* pi = new QTreeWidgetItem(projectTree, PROJECT_TYPE); pi->setText(0, s); - projectTree->addTopLevelItem(pi); - if (s == song->projectName()) + pi->setIcon(0, style()->standardIcon(QStyle::SP_FileIcon)); + if (path == song->absoluteProjectPath()) current = pi; } + else { + QDir sd(path); + QStringList dl = sd.entryList(QDir::AllDirs | QDir::NoDotAndDotDot); + if (!dl.isEmpty()) { + QTreeWidgetItem* pi = new QTreeWidgetItem(projectTree, DIR_TYPE); + pi->setText(0, s); + itemCollapsed(pi); + foreach (QString s, dl) { + processSubdir(pi, path, s, ¤t); + } + } + } } connect(projectTree, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)), SLOT(currentChanged(QTreeWidgetItem*, QTreeWidgetItem*))); connect(projectTree, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)), - SLOT(accept())); - connect(projectName, + SLOT(itemDoubleClicked(QTreeWidgetItem*, int))); + connect(projectTree, + SIGNAL(itemCollapsed(QTreeWidgetItem*)), + SLOT(itemCollapsed(QTreeWidgetItem*))); + connect(projectTree, + SIGNAL(itemExpanded(QTreeWidgetItem*)), + SLOT(itemExpanded(QTreeWidgetItem*))); + connect(projectNameEntry, SIGNAL(textEdited(const QString&)), SLOT(projectNameEdited(const QString&))); - + connect(newFolder, + SIGNAL(clicked()), + SLOT(newFolderClicked())); + if (current) projectTree->setCurrentItem(current); else currentChanged(0, 0); } +//--------------------------------------------------------- +// itemCollapsed +//--------------------------------------------------------- + +void ProjectDialog::itemCollapsed(QTreeWidgetItem* item) + { + item->setIcon(0, style()->standardIcon(QStyle::SP_DirClosedIcon)); + } + +//--------------------------------------------------------- +// itemExpanded +//--------------------------------------------------------- + +void ProjectDialog::itemExpanded(QTreeWidgetItem* item) + { + item->setIcon(0, style()->standardIcon(QStyle::SP_DirOpenIcon)); + } + +//--------------------------------------------------------- +// itemPath +//--------------------------------------------------------- + +QString ProjectDialog::itemPath(QTreeWidgetItem* item) const + { + QString path; + QTreeWidgetItem* ti = item; + QStringList dirComponent; + do { + dirComponent.prepend(ti->text(0)); + ti = ti->parent(); + } while (ti); + foreach (QString s, dirComponent) { + if (!path.isEmpty()) + path += "/"; + path += s; + } + return path; + } + //--------------------------------------------------------- // currentChanged //--------------------------------------------------------- void ProjectDialog::currentChanged(QTreeWidgetItem* item, QTreeWidgetItem*) { - bool enable = item != 0; + bool enable = (item != 0) && (item->type() == PROJECT_TYPE); createdDate->setEnabled(enable); modifiedDate->setEnabled(enable); comment->setEnabled(enable); length->setEnabled(enable); - + + // newFolder->setEnabled(item == 0 || item->type() == DIR_TYPE); if (!enable) return; - projectName->setText(item->text(0)); - QFileInfo pf(QDir::homePath() + "/" + config.projectPath + "/" - + item->text(0) + "/" + item->text(0) + ".med"); + projectNameEntry->setText(item->text(0)); + QString pd(QDir::homePath() + "/" + config.projectPath + "/"); + + pd += "/" + itemPath(item); + + QFileInfo pf(pd + "/" + item->text(0) + ".med"); createdDate->setDateTime(pf.created()); modifiedDate->setDateTime(pf.lastModified()); @@ -136,8 +233,86 @@ void ProjectDialog::currentChanged(QTreeWidgetItem* item, QTreeWidgetItem*) void ProjectDialog::projectNameEdited(const QString&) { QTreeWidgetItem* item = projectTree->currentItem(); - if (item) + if (item && item->type() == PROJECT_TYPE) { projectTree->setItemSelected(item, false); - projectTree->setCurrentItem(0); + projectTree->setCurrentItem(0); + } + } + +//--------------------------------------------------------- +// projectPath +//--------------------------------------------------------- + +QString ProjectDialog::projectPath() const + { + QTreeWidgetItem* item = projectTree->currentItem(); + QString s; + if (item) { + if (item->type() == PROJECT_TYPE) + s = itemPath(item); + else + s = itemPath(item) + "/" + projectNameEntry->text(); + } + else + s = projectNameEntry->text(); + return s; + } + +//--------------------------------------------------------- +// newFolderClicked +//--------------------------------------------------------- + +void ProjectDialog::newFolderClicked() + { + QString title(tr("MusE: create new folder")); + QString folder = QInputDialog::getText(this, title, tr("new folder:")); + if (folder.isEmpty()) + return; + QString path; + QTreeWidgetItem* item = projectTree->currentItem(); + if (item) { + QStringList sl = itemPath(item).split("/"); + int n = sl.size() - 1; + for (int i = 0; i < n; ++i) { + if (!path.isEmpty()) + path += "/"; + path += sl[i]; + } + if (!path.isEmpty()) + path += "/"; + } + path += folder; + + QDir d; + if (!d.mkpath(QDir::homePath() + "/" + config.projectPath + "/" + path)) { + QString s("Creating new project folder <%1> failed"); + QMessageBox::critical(this, title, s.arg(path)); + } + else { + if (item) + item = item->parent(); + QStringList pathElements = folder.split("/"); + foreach(QString s, pathElements) { + QTreeWidgetItem* pi; + if (item == 0) + pi = new QTreeWidgetItem(projectTree, DIR_TYPE); + else + pi = new QTreeWidgetItem(item, DIR_TYPE); + pi->setText(0, s); + itemCollapsed(pi); + item = pi; + } + projectTree->setCurrentItem(item); + } + } + +//--------------------------------------------------------- +// itemDoubleClicked +//--------------------------------------------------------- + +void ProjectDialog::itemDoubleClicked(QTreeWidgetItem* item, int) + { + if (item->type() == PROJECT_TYPE) + accept(); } diff --git a/muse/muse/projectdialog.h b/muse/muse/projectdialog.h index c0ddfee9..09593b02 100644 --- a/muse/muse/projectdialog.h +++ b/muse/muse/projectdialog.h @@ -30,13 +30,22 @@ class ProjectDialog : public QDialog, public Ui_ProjectDialogBase { Q_OBJECT + void processSubdir(QTreeWidgetItem*, const QString&, + const QString&, QTreeWidgetItem**); + + QString itemPath(QTreeWidgetItem*) const; + private slots: void currentChanged(QTreeWidgetItem*, QTreeWidgetItem*); void projectNameEdited(const QString&); + void itemCollapsed(QTreeWidgetItem*); + void itemExpanded(QTreeWidgetItem*); + void newFolderClicked(); + void itemDoubleClicked(QTreeWidgetItem*, int); public: ProjectDialog(QWidget* parent = 0); - QString project() const { return projectName->text(); } + QString projectPath() const; }; #endif diff --git a/muse/muse/projectdialog.ui b/muse/muse/projectdialog.ui index 006db8cc..ffc03eeb 100644 --- a/muse/muse/projectdialog.ui +++ b/muse/muse/projectdialog.ui @@ -15,120 +15,132 @@ MusE: Select Project - + 9 6 - - - - 0 + + + + Qt::Horizontal - - 6 + + + 221 + 20 + - - - + + + + + + create new project folder + + + ... + + + :/xpm/folder_new.png + + + + + + + + Projectlist + + + + + + + + Properties + + + + 9 + + + 3 + + + + + Qt::NoFocus + + + true + + + + + + + Qt::NoFocus + + + true + + + + + + + Qt::NoFocus + + + true + + + + + - Project + Length: - - - - - - - Properties - - - - 9 + + + + + + Comment: - - 3 + + + + + + Modified: - - - - true - - - - - - - true - - - - - - - true - - - - - - - Length: - - - - - - - Comment: - - - - - - - Modified: - - - - - - - Created: - - - - - - - - - - - - - - - 0 - - - 6 - - - - - Project: - - - - - - - + + + + + + Created: + + + + + + + Qt::NoFocus + + + true + + + + + - + 0 @@ -154,6 +166,9 @@ OK + + true + @@ -165,10 +180,47 @@ + + + + 0 + + + 6 + + + + + Project: + + + + + + + project name + + + + + - + + okButton + cancelButton + projectNameEntry + projectTree + newFolder + modifiedDate + length + createdDate + comment + + + + okButton diff --git a/muse/muse/song.cpp b/muse/muse/song.cpp index 47965f43..35e277ae 100644 --- a/muse/muse/song.cpp +++ b/muse/muse/song.cpp @@ -2356,12 +2356,21 @@ bool Song::trackExists(Track* t) const } //--------------------------------------------------------- -// projectDirectory +// absoluteProjectPath //--------------------------------------------------------- -QString Song::projectDirectory() const +QString Song::absoluteProjectPath() const { - return QDir::homePath() + "/" + config.projectPath + "/" + _projectName; + return QDir::homePath() + "/" + config.projectPath + "/" + _projectPath; + } + +//--------------------------------------------------------- +// projectPath +//--------------------------------------------------------- + +QString Song::projectPath() const + { + return _projectPath; } //--------------------------------------------------------- @@ -2370,16 +2379,17 @@ QString Song::projectDirectory() const QString Song::projectName() const { - return _projectName; + QString name = _projectPath.split("/").last(); + return name; } //--------------------------------------------------------- -// setProjectName +// setProjectPath //--------------------------------------------------------- -void Song::setProjectName(const QString& s) +void Song::setProjectPath(const QString& s) { - _projectName = s; + _projectPath = s; } //--------------------------------------------------------- @@ -2390,7 +2400,7 @@ void Song::load() { clear(false); - QString s = projectDirectory() + "/" + _projectName + ".med"; + QString s = absoluteProjectPath() + "/" + projectName() + ".med"; QFile f(s); if (f.open(QIODevice::ReadOnly)) { diff --git a/muse/muse/song.h b/muse/muse/song.h index 2317ae6d..1338de13 100644 --- a/muse/muse/song.h +++ b/muse/muse/song.h @@ -86,7 +86,7 @@ class Song : public QObject { MARKER_TICK, MARKER_LOCK }; private: - QString _projectName; + QString _projectPath; QString _comment; MidiFifo eventFifo; @@ -395,9 +395,10 @@ class Song : public QObject { void setSolo(Track*,bool); void setOff(Track*,bool); - QString projectDirectory() const; + QString projectPath() const; + QString absoluteProjectPath() const; QString projectName() const; - void setProjectName(const QString&); + void setProjectPath(const QString&); QString comment() const { return _comment; } void setComment(const QString& s) { _comment = s; } diff --git a/muse/muse/wave.cpp b/muse/muse/wave.cpp index 4bd0b262..74d71006 100644 --- a/muse/muse/wave.cpp +++ b/muse/muse/wave.cpp @@ -465,7 +465,7 @@ QString SndFile::strerror() const SndFile* SndFile::getWave(const QString& inName, bool writeFlag) { - QString name = song->projectDirectory() + "/" + inName; + QString name = song->absoluteProjectPath() + "/" + inName; // printf("=====%s %s\n", inName.toLatin1().data(), name.toLatin1().data()); SndFile* f = sndFiles.value(name); @@ -759,7 +759,7 @@ SndFile* SndFile::createRecFile(int channels) QString fileName("%1/rec%2.wav"); QFileInfo fi; do { - fi.setFile(fileName.arg(song->projectDirectory()).arg(recFileNumber)); + fi.setFile(fileName.arg(song->absoluteProjectPath()).arg(recFileNumber)); ++recFileNumber; } while (fi.exists()); SndFile* recFile = new SndFile(fi.absoluteFilePath()); diff --git a/muse/muse/waveedit/waveview.cpp b/muse/muse/waveedit/waveview.cpp index d01e8148..863a34dd 100644 --- a/muse/muse/waveedit/waveview.cpp +++ b/muse/muse/waveedit/waveview.cpp @@ -761,11 +761,11 @@ void WaveView::editExternal(unsigned file_format, unsigned file_samplerate, unsi bool WaveView::getUniqueTmpfileName(QString& newFilename) { // Check if tmp-directory exists under project path - QString tmpWavDir = song->projectDirectory() + "/tmp_musewav"; //!@TODO: Don't hardcode like this + QString tmpWavDir = song->absoluteProjectPath() + "/tmp_musewav"; //!@TODO: Don't hardcode like this QFileInfo tmpdirfi(tmpWavDir); if (!tmpdirfi.isDir()) { // Try to create a tmpdir - QDir projdir(song->projectDirectory()); + QDir projdir(song->absoluteProjectPath()); if (!projdir.mkdir("tmp_musewav")) { printf("Could not create undo dir!\n"); return false; diff --git a/muse/muse/xpm/folder_new.png b/muse/muse/xpm/folder_new.png new file mode 100644 index 00000000..1277281f Binary files /dev/null and b/muse/muse/xpm/folder_new.png differ -- cgit v1.2.3