You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
959 lines
27 KiB
959 lines
27 KiB
15 years ago
|
/*
|
||
|
|
||
|
Copyright (C) 1998 - 2000 Stefan Westerfeld
|
||
|
stefan@space.twc.de
|
||
|
|
||
|
This program is free software; you can redistribute it and/or modify
|
||
|
it under the terms of the GNU General Public License as published by
|
||
|
the Free Software Foundation; either version 2 of the License, or
|
||
|
(at your option) any later version.
|
||
|
|
||
|
This program is distributed in the hope that it will be useful,
|
||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
GNU General Public License for more details.
|
||
|
|
||
|
You should have received a copy of the GNU General Public License
|
||
|
along with this program; if not, write to the Free Software
|
||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||
|
|
||
|
*/
|
||
|
|
||
|
#include "main.h"
|
||
|
|
||
|
#include "structure.h"
|
||
|
#include "structureport.h"
|
||
|
#include "menumaker.h"
|
||
|
#include "session.h"
|
||
|
#include "dirmanager.h"
|
||
|
#include "moduleinfo.h"
|
||
|
#include "qiomanager.h"
|
||
|
#include "artsversion.h"
|
||
|
#include "propertypanel.h"
|
||
|
#include "module.h"
|
||
|
#include "autorouter.h"
|
||
|
#include "portposdlg.h"
|
||
|
#include "interfacedlg.h"
|
||
|
#include "execdlg.h"
|
||
|
#include "retrievedlg.h"
|
||
|
|
||
|
#include "config.h"
|
||
|
|
||
|
#include <kdebug.h>
|
||
|
#include <arts/debug.h>
|
||
|
#include <kaction.h>
|
||
|
#include <kstdaction.h>
|
||
|
#include <kapplication.h>
|
||
|
#include <kcmdlineargs.h>
|
||
|
#include <klocale.h>
|
||
|
#include <kinputdialog.h>
|
||
|
#include <kstdaccel.h>
|
||
|
#include <kfiledialog.h>
|
||
|
#include <ksavefile.h>
|
||
|
#include <kmessagebox.h>
|
||
|
#include <kaboutdata.h>
|
||
|
#include <kstandarddirs.h>
|
||
|
#include <kartsserver.h>
|
||
|
#include <qfile.h>
|
||
|
#include <qpopupmenu.h>
|
||
|
|
||
|
#include <soundserver.h>
|
||
|
|
||
|
#include <list>
|
||
|
#include <iostream>
|
||
|
|
||
|
#include <unistd.h>
|
||
|
#include <string.h> // strerror always here?
|
||
|
//#include <errno.h>
|
||
|
|
||
|
|
||
|
using namespace std;
|
||
|
|
||
|
/*************************************************************/
|
||
|
|
||
|
class ArtsBuilderApp :public KApplication
|
||
|
{
|
||
|
protected:
|
||
|
ArtsBuilderWindow *mainWindow;
|
||
|
|
||
|
public:
|
||
|
ArtsBuilderApp();
|
||
|
ArtsBuilderApp(QString filename);
|
||
|
void start();
|
||
|
void end();
|
||
|
};
|
||
|
|
||
|
/*************************************************************/
|
||
|
|
||
|
ArtsBuilderWindow::ArtsBuilderWindow(const char *name)
|
||
|
: KDockMainWindow(0, name),
|
||
|
mainDock(0),
|
||
|
modulewidget(0),
|
||
|
propertyDock(0),
|
||
|
propertyPanel(0),
|
||
|
menumaker(0),
|
||
|
structure(0),
|
||
|
execDlg(0)
|
||
|
{
|
||
|
#if 0 /* PORT */
|
||
|
ModuleBroker = Synthesizer->moduleBroker();
|
||
|
assert(ModuleBroker);
|
||
|
|
||
|
//---- publish my widgets on the server ----
|
||
|
|
||
|
GUIServer = new GUIServer_impl(ModuleBroker, Synthesizer);
|
||
|
arts_debug("GUIServer:\n%s", ArtsOrb->object_to_string(GUIServer));
|
||
|
GUIServer->incRef();
|
||
|
|
||
|
//---- trigger autoloading of all structures that are present in my dirs ----
|
||
|
|
||
|
list<string> datadirs = PortableKDE::globalDirs("data");
|
||
|
list<string>::iterator it;
|
||
|
|
||
|
for(it = datadirs.begin(); it != datadirs.end(); ++it)
|
||
|
{
|
||
|
string common = *it;
|
||
|
common += "artsbuilder";
|
||
|
if(chdir(common.c_str()) == 0)
|
||
|
ModuleBroker->addPublishingPath(common.c_str());
|
||
|
}
|
||
|
/*
|
||
|
string common = (const char *)PortableKDE::globalDir("data");
|
||
|
common += "/artsbuilder";
|
||
|
arts_debug("%s", common.c_str());
|
||
|
if(chdir(common.c_str()) == 0)
|
||
|
ModuleBroker->addPublishingPath(common.c_str());
|
||
|
*/
|
||
|
|
||
|
// just make sure that the mapsDir exists
|
||
|
(void)DirManager::mapDir();
|
||
|
|
||
|
if(chdir(DirManager::structureDir()) == 0) // retry
|
||
|
{
|
||
|
ModuleBroker->addPublishingPath(DirManager::structureDir());
|
||
|
Synthesizer->addArtsDirectory(DirManager::baseDir());
|
||
|
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
arts_debug("PORT: structure");
|
||
|
structure = new Structure();
|
||
|
arts_debug("PORT: structure ok");
|
||
|
//ModuleList = structure->getModuleList();
|
||
|
|
||
|
mainDock = createDockWidget("mainDockWidget", 0, 0, "main_dock_widget");
|
||
|
|
||
|
arts_debug("PORT: modulewidget");
|
||
|
modulewidget = new ModuleWidget(structure, mainDock, "mwidget");
|
||
|
mainDock->setWidget(modulewidget);
|
||
|
connect(modulewidget, SIGNAL(modified(bool)), SLOT(setModified(bool)));
|
||
|
arts_debug("PORT: modulewidget ok");
|
||
|
|
||
|
// allow others to dock to the 4 sides
|
||
|
mainDock->setDockSite(KDockWidget::DockCorner);
|
||
|
// forbit docking abilities of module widget itself
|
||
|
mainDock->setEnableDocking(KDockWidget::DockNone);
|
||
|
|
||
|
setView(mainDock);
|
||
|
setMainDockWidget(mainDock);
|
||
|
|
||
|
propertyDock = createDockWidget("propertyDock", 0, 0, i18n("Port Properties"));
|
||
|
|
||
|
propertyPanel = new PropertyPanel(propertyDock, "ppanel");
|
||
|
|
||
|
propertyDock->setWidget(propertyPanel);
|
||
|
propertyDock->manualDock(mainDock, // dock target
|
||
|
KDockWidget::DockBottom, // dock site
|
||
|
80); // relation target/this (in percent)
|
||
|
|
||
|
// selection
|
||
|
connect(modulewidget, SIGNAL(portSelected(ModulePort *)),
|
||
|
propertyPanel, SLOT (setSelectedPort(ModulePort *)));
|
||
|
connect(propertyPanel, SIGNAL(portSelected(ModulePort *)),
|
||
|
modulewidget, SLOT (selectPort(ModulePort *)));
|
||
|
connect(modulewidget, SIGNAL(componentSelected(StructureComponent *)),
|
||
|
propertyPanel, SLOT (setSelectedComponent(StructureComponent *)));
|
||
|
|
||
|
// connection
|
||
|
connect(propertyPanel, SIGNAL(startConnection(ModulePort *)),
|
||
|
modulewidget, SLOT (startConnection(ModulePort *)));
|
||
|
|
||
|
// port properties changed
|
||
|
connect(propertyPanel, SIGNAL(portPropertiesChanged(ModulePort *)),
|
||
|
modulewidget, SLOT (portPropertiesChanged(ModulePort *)));
|
||
|
|
||
|
arts_debug("PORT: setcanvas");
|
||
|
structure->setCanvas(modulewidget);
|
||
|
arts_debug("PORT: setcanvas ok");
|
||
|
|
||
|
mbroker_updateCount = 0;
|
||
|
|
||
|
arts_debug("PORT: menumaker");
|
||
|
menumaker = new MenuMaker(new KActionMenu(i18n("Modules"), actionCollection(), "modulesmenu"));
|
||
|
//menumaker->addCategory("&Gui", "Gui_");
|
||
|
menumaker->addCategory(i18n("&Synthesis"), "Arts::Synth_");
|
||
|
menumaker->addCategory(i18n("&Synthesis/&Arithmetic + Mixing"), "Arts::Synth_ADD$");
|
||
|
menumaker->addCategory(i18n("&Synthesis/&Arithmetic + Mixing"), "Arts::Synth_AUTOPANNER$");
|
||
|
menumaker->addCategory(i18n("&Synthesis/&Arithmetic + Mixing"), "Arts::Synth_MUL$");
|
||
|
menumaker->addCategory(i18n("&Synthesis/&Arithmetic + Mixing"), "Arts::Synth_DIV$");
|
||
|
menumaker->addCategory(i18n("&Synthesis/&Arithmetic + Mixing"), "Arts::Synth_MULTI_ADD$");
|
||
|
menumaker->addCategory(i18n("&Synthesis/&Arithmetic + Mixing"), "Arts::Synth_XFADE$");
|
||
|
menumaker->addCategory(i18n("&Synthesis/&Busses"), "Arts::Synth_BUS_");
|
||
|
menumaker->addCategory(i18n("&Synthesis/&Delays"), "Arts::Synth_DELAY$");
|
||
|
menumaker->addCategory(i18n("&Synthesis/&Delays"), "Arts::Synth_CDELAY$");
|
||
|
menumaker->addCategory(i18n("&Synthesis/&Envelopes"), "Arts::Synth_PSCALE$");
|
||
|
menumaker->addCategory(i18n("&Synthesis/&Envelopes"), "Arts::Synth_ENVELOPE_");
|
||
|
menumaker->addCategory(i18n("&Synthesis/Effe&cts"), "Arts::Synth_FREEVERB$");
|
||
|
menumaker->addCategory(i18n("&Synthesis/Effe&cts"), "Arts::Synth_FX_");
|
||
|
menumaker->addCategory(i18n("&Synthesis/Effe&cts"), "Arts::Synth_PITCH_SHIFT$");
|
||
|
menumaker->addCategory(i18n("&Synthesis/Effe&cts"), "Arts::Synth_TREMOLO$");
|
||
|
menumaker->addCategory(i18n("&Synthesis/&Filters"), "Arts::Synth_ATAN_SATURATE$");
|
||
|
menumaker->addCategory(i18n("&Synthesis/&Filters"), "Arts::Synth_BRICKWALL_LIMITER$");
|
||
|
menumaker->addCategory(i18n("&Synthesis/&Filters"), "Arts::Synth_MOOG_VCF");
|
||
|
menumaker->addCategory(i18n("&Synthesis/&Filters"), "Arts::Synth_SHELVE_CUTOFF$");
|
||
|
menumaker->addCategory(i18n("&Synthesis/&Filters"), "Arts::Synth_RC$");
|
||
|
menumaker->addCategory(i18n("&Synthesis/&Filters"), "Arts::Synth_STD_EQUALIZER$");
|
||
|
menumaker->addCategory(i18n("&Synthesis/&Midi + Sequencing"), "Arts::Synth_MIDI");
|
||
|
menumaker->addCategory(i18n("&Synthesis/&Midi + Sequencing"), "Arts::Interface_MIDI");
|
||
|
menumaker->addCategory(i18n("&Synthesis/&Midi + Sequencing"), "Arts::Synth_SEQUENCE$");
|
||
|
menumaker->addCategory(i18n("&Synthesis/&Midi + Sequencing"), "Arts::Synth_SEQUENCE_FREQ$");
|
||
|
menumaker->addCategory(i18n("&Synthesis/&Midi + Sequencing"), "Arts::Synth_STRUCT_KILL$");
|
||
|
menumaker->addCategory(i18n("&Synthesis/Sam&ples "), "Arts::Synth_PLAY_");
|
||
|
menumaker->addCategory(i18n("&Synthesis/&Sound IO"), "Arts::Synth_AMAN_");
|
||
|
menumaker->addCategory(i18n("&Synthesis/&Sound IO"), "Arts::Synth_CAPTURE_WAV$");
|
||
|
menumaker->addCategory(i18n("&Synthesis/&Sound IO"), "Arts::Synth_PLAY$");
|
||
|
menumaker->addCategory(i18n("&Synthesis/&Sound IO"), "Arts::Synth_RECORD$");
|
||
|
menumaker->addCategory(i18n("&Synthesis/&Sound IO"), "Arts::Synth_FULL_DUPLEX_");
|
||
|
menumaker->addCategory(i18n("&Synthesis/&Sound IO"), "Arts::Synth_FILEPLAY");
|
||
|
menumaker->addCategory(i18n("&Synthesis/&Tests"), "Arts::Synth_NIL$");
|
||
|
menumaker->addCategory(i18n("&Synthesis/&Tests"), "Arts::Synth_DEBUG$");
|
||
|
menumaker->addCategory(i18n("&Synthesis/&Tests"), "Arts::Synth_DATA$");
|
||
|
menumaker->addCategory(i18n("&Synthesis/&Tests"), "Arts::Synth_MIDI_DEBUG$");
|
||
|
menumaker->addCategory(i18n("&Synthesis/&Oscillation && Modulation"), "Arts::Synth_FREQUENCY$");
|
||
|
menumaker->addCategory(i18n("&Synthesis/&Oscillation && Modulation"), "Arts::Synth_FM_SOURCE$");
|
||
|
menumaker->addCategory(i18n("&Synthesis/&Oscillation && Modulation"), "Arts::Synth_OSC$");
|
||
|
menumaker->addCategory(i18n("&Synthesis/&WaveForms"), "Arts::Synth_WAVE_");
|
||
|
menumaker->addCategory(i18n("&Synthesis/&WaveForms"), "Arts::Synth_NOISE$");
|
||
|
menumaker->addCategory(i18n("&Synthesis/&Internal"), "Arts::Synth_PARAM_");
|
||
|
|
||
|
menumaker->addCategory(i18n("&Examples"), "example_");
|
||
|
menumaker->addCategory(i18n("&Instruments"), "instrument_");
|
||
|
menumaker->addCategory(i18n("&Mixer-Elements"), "mixer_element_");
|
||
|
menumaker->addCategory(i18n("&Templates"), "template_");
|
||
|
menumaker->addCategory(i18n("&Other"), "*");
|
||
|
arts_debug("PORT: menumaker ok");
|
||
|
|
||
|
/*
|
||
|
m_modules->insertItem(i18n("&Gui"), m_modules_gui);
|
||
|
m_modules->insertItem(i18n("&Synthesis"), m_modules_synth);
|
||
|
m_modules->insertItem(i18n("&Instruments"), m_modules_instruments);
|
||
|
m_modules->insertItem(i18n("&Other"), m_modules_other);
|
||
|
*/
|
||
|
|
||
|
#if 000
|
||
|
connect(menubar, SIGNAL(highlighted(int)), this, SLOT(activateMenu(int)));
|
||
|
connect(m_view, SIGNAL(activated(int)), modulewidget, SLOT(setZoom(int)));
|
||
|
connect(m_ports, SIGNAL(activated(int)), this, SLOT(addPort(int)));
|
||
|
connect(m_file_new, SIGNAL(activated(int)), this, SLOT(fileNew(int)));
|
||
|
|
||
|
//connect(m_modules, SIGNAL(activated(int)), this, SLOT(addModule(int)));
|
||
|
/*
|
||
|
connect(m_modules_synth, SIGNAL(activated(int)), this, SLOT(addModule(int)));
|
||
|
connect(m_modules_gui, SIGNAL(activated(int)), this, SLOT(addModule(int)));
|
||
|
connect(m_modules_instruments, SIGNAL(activated(int)), this, SLOT(addModule(int)));
|
||
|
connect(m_modules_other, SIGNAL(activated(int)), this, SLOT(addModule(int)));
|
||
|
*/
|
||
|
connect(kapp, SIGNAL(lastWindowClosed()), this , SLOT(quit()));
|
||
|
|
||
|
// update the modules menu once for the start
|
||
|
#endif
|
||
|
|
||
|
arts_debug("PORT: activatemenu");
|
||
|
connect(menumaker, SIGNAL(activated(const char *)), this, SLOT(addModule(const char *)));
|
||
|
fillModuleMenu();
|
||
|
arts_debug("PORT: activatemenu ok");
|
||
|
setupActions();
|
||
|
|
||
|
createGUI();
|
||
|
|
||
|
// connect to aboutToShow to correctly show state of dockwidget there:
|
||
|
QPopupMenu *viewmenu = (QPopupMenu*)factory()->container("view", this);
|
||
|
if (viewmenu)
|
||
|
connect(viewmenu, SIGNAL(aboutToShow()), this, SLOT(viewMenuAboutToShow()));
|
||
|
else
|
||
|
arts_debug("view menu not found!");
|
||
|
|
||
|
m_filename = QString::null;
|
||
|
setModified(false);
|
||
|
|
||
|
installEventFilter(propertyPanel);
|
||
|
}
|
||
|
|
||
|
void ArtsBuilderWindow::setupActions()
|
||
|
{
|
||
|
// File menu
|
||
|
KStdAction::openNew(this, SLOT(fileNew()), actionCollection());
|
||
|
|
||
|
(void)new KAction(i18n("Open Session..."), 0, this, SLOT(openSession()),
|
||
|
actionCollection(), "file_open_session");
|
||
|
KStdAction::open(this, SLOT(open()), actionCollection());
|
||
|
(void)new KAction(i18n("Open E&xample..."), Qt::CTRL + Qt::Key_X, this, SLOT(openExample()),
|
||
|
actionCollection(), "file_open_example");
|
||
|
KStdAction::save(this, SLOT(save()), actionCollection());
|
||
|
KStdAction::saveAs(this, SLOT(saveAs()), actionCollection());
|
||
|
(void)new KAction(i18n("&Retrieve From Server..."), Qt::CTRL + Qt::Key_R, this, SLOT(retrieve()),
|
||
|
actionCollection(), "file_retrieve_from_server");
|
||
|
(void)new KAction(i18n("&Execute Structure"), "artsbuilderexecute", Qt::CTRL + Qt::Key_E, this, SLOT(execute()),
|
||
|
actionCollection(), "file_execute_structure");
|
||
|
(void)new KAction(i18n("&Rename Structure..."), Qt::CTRL + Qt::Key_R, this, SLOT(rename()),
|
||
|
actionCollection(), "file_rename_structure");
|
||
|
(void)new KAction(i18n("&Publish Structure"), Qt::CTRL + Qt::Key_P, this, SLOT(publish()),
|
||
|
actionCollection(), "file_publish_structure");
|
||
|
KStdAction::quit(this, SLOT(close()), actionCollection());
|
||
|
|
||
|
// Edit menu
|
||
|
(void)new KAction(i18n("&Delete"), Qt::Key_Delete, modulewidget, SLOT(delModule()),
|
||
|
actionCollection(), "edit_delete");
|
||
|
KStdAction::selectAll(modulewidget, SLOT(selectAll()), actionCollection());
|
||
|
|
||
|
// View menu
|
||
|
viewPropertiesAction= new KToggleAction(i18n("&Property Panel"), 0,
|
||
|
propertyDock, SLOT(changeHideShowState()),
|
||
|
actionCollection(), "view_properties");
|
||
|
(void)new KAction(i18n("200%"), 0, this, SLOT(viewAt200()),
|
||
|
actionCollection(), "view_200");
|
||
|
(void)new KAction(i18n("150%"), 0, this, SLOT(viewAt150()),
|
||
|
actionCollection(), "view_150");
|
||
|
(void)new KAction(i18n("100%"), 0, this, SLOT(viewAt100()),
|
||
|
actionCollection(), "view_100");
|
||
|
(void)new KAction(i18n("50%"), 0, this, SLOT(viewAt50()),
|
||
|
actionCollection(), "view_50");
|
||
|
|
||
|
// Ports menu
|
||
|
(void)new KAction(i18n("Create IN Audio Signal"), 0, this, SLOT(createInAudioSignal()),
|
||
|
actionCollection(), "ports_create_in_audio_signal");
|
||
|
(void)new KAction(i18n("Create OUT Audio Signal"), 0, this, SLOT(createOutAudioSignal()),
|
||
|
actionCollection(), "ports_create_out_audio_signal");
|
||
|
(void)new KAction(i18n("Create IN String Property"), 0, this, SLOT(createInStringProperty()),
|
||
|
actionCollection(), "ports_create_in_string_property");
|
||
|
(void)new KAction(i18n("Create IN Audio Property"), 0, this, SLOT(createInAudioProperty()),
|
||
|
actionCollection(), "ports_create_in_audio_property");
|
||
|
(void)new KAction(i18n("Implement Interface..."), 0, this, SLOT(addInterface()),
|
||
|
actionCollection(), "ports_implement_interface");
|
||
|
(void)new KAction(i18n("Change Positions/Names..."), 0, this, SLOT(changePortPositions()),
|
||
|
actionCollection(), "ports_change_positions");
|
||
|
}
|
||
|
|
||
|
void ArtsBuilderWindow::fillModuleMenu()
|
||
|
{
|
||
|
long updateCount = 3; /* PORT: automatic update of menues missing */
|
||
|
|
||
|
if(updateCount != mbroker_updateCount)
|
||
|
{
|
||
|
mbroker_updateCount = updateCount;
|
||
|
//---- query all available objects ----
|
||
|
Arts::TraderQuery query;
|
||
|
query.supports("Buildable", "true");
|
||
|
vector<Arts::TraderOffer> *offers = query.query();
|
||
|
|
||
|
menumaker->clear();
|
||
|
//m_file_new->clear();
|
||
|
|
||
|
vector<Arts::TraderOffer>::iterator i;
|
||
|
long n = 1; /* TODO:PORT: is this necessary? I think not */
|
||
|
for(i = offers->begin(); i != offers->end(); ++i)
|
||
|
{
|
||
|
Arts::TraderOffer& offer = *i;
|
||
|
string name = offer.interfaceName();
|
||
|
menumaker->addItem(name.c_str(),n++);
|
||
|
|
||
|
/* PORT: templates missing
|
||
|
if(strncmp(name, "template_", strlen("template_")) == 0)
|
||
|
{
|
||
|
char *xname = strdup(&name[strlen("template_")]);
|
||
|
int x;
|
||
|
for(x = 0;xname[x] != 0; x++)
|
||
|
if(xname[x] == '_') xname[x] = ' ';
|
||
|
|
||
|
m_file_new->insertItem(xname, i);
|
||
|
}
|
||
|
*/
|
||
|
}
|
||
|
delete offers;
|
||
|
}
|
||
|
#if 0
|
||
|
if(0) /*item == modules_menu_item) PORT!!! */
|
||
|
{
|
||
|
long updateCount = ModuleBroker->updateCount();
|
||
|
|
||
|
// if the contents of the ModukeBroker changed, update our "modules"-Menu
|
||
|
if(updateCount != mbroker_updateCount)
|
||
|
{
|
||
|
mbroker_updateCount = updateCount;
|
||
|
//---- query all available objects ----
|
||
|
ArtsCorba::StringSeq_var Modules = ModuleBroker->publishedModules();
|
||
|
assert(Modules);
|
||
|
|
||
|
menumaker->clear();
|
||
|
m_file_new->clear();
|
||
|
|
||
|
unsigned long i;
|
||
|
for(i = 0; i < Modules->length();i++)
|
||
|
{
|
||
|
const char *name = (*Modules)[i];
|
||
|
menumaker->addItem(name, i);
|
||
|
|
||
|
if(strncmp(name, "template_", strlen("template_")) == 0)
|
||
|
{
|
||
|
char *xname = strdup(&name[strlen("template_")]);
|
||
|
int x;
|
||
|
for(x = 0;xname[x] != 0; x++)
|
||
|
if(xname[x] == '_') xname[x] = ' ';
|
||
|
|
||
|
m_file_new->insertItem(xname, i);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
void ArtsBuilderWindow::quit()
|
||
|
{
|
||
|
if(execDlg) return;
|
||
|
arts_debug(">> ArtsBuilderWindow::quit() called");
|
||
|
kapp->quit();
|
||
|
arts_debug("<< leaving ArtsBuilderWindow::quit()");
|
||
|
}
|
||
|
|
||
|
ArtsBuilderWindow::~ArtsBuilderWindow()
|
||
|
{
|
||
|
delete structure;
|
||
|
}
|
||
|
|
||
|
void ArtsBuilderWindow::viewMenuAboutToShow()
|
||
|
{
|
||
|
viewPropertiesAction->setChecked(propertyDock->isVisible());
|
||
|
}
|
||
|
|
||
|
void ArtsBuilderWindow::publish()
|
||
|
{
|
||
|
checkName();
|
||
|
structure->publish();
|
||
|
KMessageBox::information(this,
|
||
|
i18n("The structure has been published as: '%1' on the server.").arg( structure->name().c_str() ));
|
||
|
}
|
||
|
|
||
|
QString ArtsBuilderWindow::getOpenFilename(const char *pattern, const char *initialDir)
|
||
|
{
|
||
|
arts_debug(">>>>> getOpenFilename");
|
||
|
QString filename = KFileDialog::getOpenFileName(initialDir, pattern, this);
|
||
|
arts_debug(">>>>> opendlg closed");
|
||
|
if(!filename.isEmpty())
|
||
|
{
|
||
|
arts_debug("open... %s", filename.local8Bit().data());
|
||
|
|
||
|
// check that the file is ok:
|
||
|
|
||
|
FILE *infile = fopen(QFile::encodeName(filename), "r");
|
||
|
|
||
|
if(infile)
|
||
|
{
|
||
|
fclose(infile);
|
||
|
return(filename);
|
||
|
}
|
||
|
}
|
||
|
return QString("");
|
||
|
}
|
||
|
|
||
|
void ArtsBuilderWindow::fileNew()
|
||
|
{
|
||
|
if(!promptToSave())
|
||
|
return;
|
||
|
|
||
|
propertyPanel->setSelectedComponent(0);
|
||
|
structure->clear();
|
||
|
modulewidget->reInit();
|
||
|
m_filename = QString::null;
|
||
|
setModified(false);
|
||
|
}
|
||
|
|
||
|
void ArtsBuilderWindow::open()
|
||
|
{
|
||
|
if(!promptToSave())
|
||
|
return;
|
||
|
|
||
|
open(getOpenFilename("*.arts", DirManager::structureDir()));
|
||
|
}
|
||
|
|
||
|
void ArtsBuilderWindow::open(QString filename)
|
||
|
{
|
||
|
if(!promptToSave())
|
||
|
return;
|
||
|
|
||
|
if(!filename.isEmpty())
|
||
|
{
|
||
|
structure->load(QFile::encodeName(filename));
|
||
|
modulewidget->reInit();
|
||
|
if(!structure->valid())
|
||
|
{
|
||
|
KMessageBox::sorry(this,
|
||
|
i18n("The structure could not be loaded correctly. Maybe some of\n"
|
||
|
"the modules used in the file are not available in this\n"
|
||
|
"version of aRts."),
|
||
|
i18n("Arts Warning"));
|
||
|
}
|
||
|
m_filename = filename;
|
||
|
setModified(false);
|
||
|
setCaption(m_filename);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void ArtsBuilderWindow::openSession()
|
||
|
{
|
||
|
if(!promptToSave())
|
||
|
return;
|
||
|
|
||
|
QString filename = getOpenFilename("*.arts-session", DirManager::sessionDir());
|
||
|
|
||
|
if(!filename.isEmpty())
|
||
|
{
|
||
|
Session *session = new Session();
|
||
|
session->loadSession(QFile::encodeName(filename));
|
||
|
|
||
|
assert(!execDlg);
|
||
|
execDlg = new ExecDlg(0, session);
|
||
|
assert(execDlg);
|
||
|
|
||
|
// this will create the widgets that will eventually get into the
|
||
|
// execdlg
|
||
|
session->startExecute();
|
||
|
|
||
|
execDlg->start();
|
||
|
execDlg->show();
|
||
|
|
||
|
connect(execDlg, SIGNAL(ready()), this, SLOT(endexecute()));
|
||
|
|
||
|
hide();
|
||
|
// m_filename = filename; FIXME: DOESN'T THIS BELONG HERE?
|
||
|
setModified(false);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void ArtsBuilderWindow::openExample()
|
||
|
{
|
||
|
if(!promptToSave())
|
||
|
return;
|
||
|
|
||
|
QString dir = locate("data", "artsbuilder/examples/");
|
||
|
if(!dir)
|
||
|
KMessageBox::sorry(
|
||
|
this,
|
||
|
i18n("Unable to find the examples folder.\nUsing the current folder instead."),
|
||
|
i18n("aRts Warning"));
|
||
|
|
||
|
open(getOpenFilename("*.arts", QFile::encodeName(dir)));
|
||
|
}
|
||
|
|
||
|
void ArtsBuilderWindow::saveAs()
|
||
|
{
|
||
|
checkName();
|
||
|
string defaultname = string(structure->name()) + string(".arts");
|
||
|
|
||
|
chdir(DirManager::structureDir());
|
||
|
KFileDialog *dlg = new KFileDialog(0, "*.arts", this, 0, true /*,false TODO: acceptURLs */);
|
||
|
|
||
|
dlg->setSelection(defaultname.c_str());
|
||
|
dlg->setCaption(i18n("Save As"));
|
||
|
|
||
|
QString filename;
|
||
|
if(dlg->exec() == QDialog::Accepted)
|
||
|
filename = dlg->selectedFile();
|
||
|
|
||
|
delete dlg;
|
||
|
// QString filename = KFileDialog::getSaveFileName(0, "*.arts", this);
|
||
|
// filename.detach();
|
||
|
|
||
|
if(!filename.isEmpty())
|
||
|
save(filename);
|
||
|
}
|
||
|
|
||
|
bool ArtsBuilderWindow::save(QString filename)
|
||
|
{
|
||
|
arts_debug("trying to save structure as '%s'", filename.local8Bit().data());
|
||
|
|
||
|
KSaveFile file(filename);
|
||
|
|
||
|
if(file.status()) {
|
||
|
KMessageBox::sorry(this,
|
||
|
i18n("The file '%1' could not be opened for writing: %2")
|
||
|
.arg(filename).arg(strerror(file.status())),
|
||
|
i18n("aRts Warning"));
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
structure->saveInto(file.fstream());
|
||
|
|
||
|
if(!file.close()) {
|
||
|
KMessageBox::sorry(this,
|
||
|
i18n("Saving to file '%1' could not be finished correctly: %2")
|
||
|
.arg(filename).arg(strerror(file.status())),
|
||
|
i18n("aRts Warning"));
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
// tell the server to rescan for structures
|
||
|
Arts::SoundServerV2 server = KArtsServer().server();
|
||
|
if(!server.isNull()) server.checkNewObjects();
|
||
|
|
||
|
m_filename = filename;
|
||
|
setModified(false);
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
void ArtsBuilderWindow::save()
|
||
|
{
|
||
|
if(m_filename.isEmpty())
|
||
|
saveAs();
|
||
|
else
|
||
|
save(m_filename);
|
||
|
}
|
||
|
|
||
|
void ArtsBuilderWindow::checkName()
|
||
|
{
|
||
|
if(strncmp(structure->name().c_str(), "template_", strlen("template_")) == 0)
|
||
|
rename();
|
||
|
}
|
||
|
|
||
|
void ArtsBuilderWindow::rename()
|
||
|
{
|
||
|
bool ok;
|
||
|
|
||
|
QString name = KInputDialog::getText( i18n( "Rename Structure" ),
|
||
|
i18n( "Enter structure name:" ), structure->name().c_str(), &ok, this );
|
||
|
if (ok)
|
||
|
{
|
||
|
arts_debug("rename OK...");
|
||
|
structure->rename(name.local8Bit());
|
||
|
}
|
||
|
|
||
|
setModified(true);
|
||
|
}
|
||
|
|
||
|
void ArtsBuilderWindow::retrieve()
|
||
|
{
|
||
|
if(!promptToSave())
|
||
|
return;
|
||
|
|
||
|
RetrieveDlg rd(0);
|
||
|
|
||
|
if(rd.exec())
|
||
|
{
|
||
|
QString result = rd.result();
|
||
|
if(!result.isEmpty())
|
||
|
{
|
||
|
structure->retrieve(result.local8Bit());
|
||
|
modulewidget->reInit();
|
||
|
}
|
||
|
}
|
||
|
// maybe set m_filename to null or sth. here?
|
||
|
setModified(true);
|
||
|
}
|
||
|
|
||
|
void ArtsBuilderWindow::execute()
|
||
|
{
|
||
|
assert(structure);
|
||
|
assert(!execDlg);
|
||
|
execDlg = new ExecDlg(0, structure);
|
||
|
assert(execDlg);
|
||
|
|
||
|
// this will create the widgets that will eventually get into the
|
||
|
// execdlg
|
||
|
if(structure->startExecute())
|
||
|
{
|
||
|
execDlg->start();
|
||
|
execDlg->show();
|
||
|
|
||
|
connect(execDlg, SIGNAL(ready()), this, SLOT(endexecute()));
|
||
|
|
||
|
hide();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
delete execDlg;
|
||
|
execDlg = 0;
|
||
|
|
||
|
KMessageBox::sorry(this,
|
||
|
i18n("Could not execute your structure. Make sure that the\n"
|
||
|
"sound server (artsd) is running.\n"), i18n("aRts Warning"));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void ArtsBuilderWindow::endexecute()
|
||
|
{
|
||
|
show();
|
||
|
assert(execDlg);
|
||
|
delete execDlg;
|
||
|
// will be done by the execDlg itself now
|
||
|
//structure->stopExecute();
|
||
|
|
||
|
execDlg = 0;
|
||
|
}
|
||
|
|
||
|
void ArtsBuilderWindow::oldFileNewWhatTheHellDoesItDo(int what)
|
||
|
{
|
||
|
if(!promptToSave())
|
||
|
return;
|
||
|
|
||
|
const char *name = menumaker->findID(what);
|
||
|
assert(name);
|
||
|
structure->retrieve(name);
|
||
|
modulewidget->reInit();
|
||
|
setModified(false);
|
||
|
}
|
||
|
|
||
|
void ArtsBuilderWindow::createInAudioSignal()
|
||
|
{
|
||
|
// data that goes into the structure
|
||
|
modulewidget->addPort(Arts::PortType(Arts::output, "float", Arts::conn_stream, false));
|
||
|
setModified(true);
|
||
|
}
|
||
|
|
||
|
void ArtsBuilderWindow::createOutAudioSignal()
|
||
|
{
|
||
|
// data that goes out of the structure
|
||
|
modulewidget->addPort(Arts::PortType(Arts::input, "float", Arts::conn_stream, false));
|
||
|
setModified(true);
|
||
|
}
|
||
|
|
||
|
void ArtsBuilderWindow::createInStringProperty()
|
||
|
{
|
||
|
// data that goes into the structure
|
||
|
modulewidget->addPort(Arts::PortType(Arts::output, "string", Arts::conn_property, false));
|
||
|
setModified(true);
|
||
|
}
|
||
|
|
||
|
void ArtsBuilderWindow::createInAudioProperty()
|
||
|
{
|
||
|
// data that goes into the structure
|
||
|
modulewidget->addPort(Arts::PortType(Arts::output, "float", Arts::conn_property, false));
|
||
|
setModified(true);
|
||
|
}
|
||
|
|
||
|
void ArtsBuilderWindow::changePortPositions()
|
||
|
{
|
||
|
PortPosDlg *ppd = new PortPosDlg(this, structure);
|
||
|
ppd->exec();
|
||
|
setModified(true);
|
||
|
// XXX: delete ppd?
|
||
|
}
|
||
|
|
||
|
void ArtsBuilderWindow::addInterface()
|
||
|
{
|
||
|
InterfaceDlg *ifd = new InterfaceDlg(this);
|
||
|
ifd->exec();
|
||
|
|
||
|
Arts::ModuleInfo minfo = makeModuleInfo(ifd->interfaceName());
|
||
|
if(!minfo.name.empty())
|
||
|
modulewidget->addInterface(minfo);
|
||
|
|
||
|
delete ifd;
|
||
|
}
|
||
|
|
||
|
void ArtsBuilderWindow::viewAt50()
|
||
|
{
|
||
|
modulewidget->setZoom(50);
|
||
|
}
|
||
|
|
||
|
void ArtsBuilderWindow::viewAt100()
|
||
|
{
|
||
|
modulewidget->setZoom(100);
|
||
|
}
|
||
|
|
||
|
void ArtsBuilderWindow::viewAt150()
|
||
|
{
|
||
|
modulewidget->setZoom(150);
|
||
|
}
|
||
|
|
||
|
void ArtsBuilderWindow::viewAt200()
|
||
|
{
|
||
|
modulewidget->setZoom(200);
|
||
|
}
|
||
|
|
||
|
void ArtsBuilderWindow::addModule(const char *name)
|
||
|
{
|
||
|
arts_return_if_fail (name != 0);
|
||
|
|
||
|
arts_debug("addModule(%s)", name);
|
||
|
Arts::ModuleInfo minfo = makeModuleInfo(name);
|
||
|
|
||
|
if(!minfo.name.empty())
|
||
|
modulewidget->addModule(minfo);
|
||
|
#if 0
|
||
|
const char *name = menumaker->findID(module);
|
||
|
assert(name);
|
||
|
|
||
|
arts_debug("selected (%s) (module=%d)", name, module);
|
||
|
|
||
|
ArtsCorba::ModuleBroker_var ModuleBroker = Synthesizer->moduleBroker();
|
||
|
ArtsCorba::ModuleInfo_var minfo = ModuleBroker->lookupModule(name);
|
||
|
|
||
|
|
||
|
if(minfo)
|
||
|
{
|
||
|
modulewidget->addModule(minfo);
|
||
|
|
||
|
/*
|
||
|
Module *m = structure->createModule(minfo);
|
||
|
modulewidget->addModule(m);
|
||
|
*/
|
||
|
}
|
||
|
#endif
|
||
|
setModified(true);
|
||
|
}
|
||
|
|
||
|
bool ArtsBuilderWindow::isModified()
|
||
|
{
|
||
|
return modified;
|
||
|
}
|
||
|
|
||
|
void ArtsBuilderWindow::setModified(bool m)
|
||
|
{
|
||
|
modified = m;
|
||
|
setCaption(m_filename, modified);
|
||
|
actionCollection()->action(KStdAction::stdName(KStdAction::Save))->setEnabled(modified);
|
||
|
}
|
||
|
|
||
|
bool ArtsBuilderWindow::queryClose()
|
||
|
{
|
||
|
return promptToSave();
|
||
|
}
|
||
|
|
||
|
bool ArtsBuilderWindow::promptToSave()
|
||
|
{
|
||
|
bool result;
|
||
|
int query;
|
||
|
|
||
|
if(!isModified())
|
||
|
return true;
|
||
|
|
||
|
query = KMessageBox::warningYesNoCancel(this,
|
||
|
i18n("The current structure has been modified.\nWould you like to save it?"), QString::null, KStdGuiItem::save(), KStdGuiItem::discard());
|
||
|
|
||
|
result = false;
|
||
|
switch(query)
|
||
|
{
|
||
|
case KMessageBox::Yes:
|
||
|
save();
|
||
|
result = !modified;
|
||
|
break;
|
||
|
case KMessageBox::No:
|
||
|
result = true;
|
||
|
setModified(false);
|
||
|
break;
|
||
|
case KMessageBox::Cancel:
|
||
|
break;
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
/*************************************************************/
|
||
|
|
||
|
ArtsBuilderApp::ArtsBuilderApp()
|
||
|
{
|
||
|
start();
|
||
|
}
|
||
|
|
||
|
ArtsBuilderApp::ArtsBuilderApp(QString filename)
|
||
|
{
|
||
|
start();
|
||
|
if(QFile::exists(filename))
|
||
|
{
|
||
|
mainWindow->open(filename);
|
||
|
} else {
|
||
|
KMessageBox::sorry(0,
|
||
|
i18n("The specified file '%1' does not exist.").arg(filename),
|
||
|
i18n("aRts Warning"));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void ArtsBuilderApp::start()
|
||
|
{
|
||
|
arts_debug("PORT: mainWindow");
|
||
|
mainWindow = new ArtsBuilderWindow("main");
|
||
|
|
||
|
arts_debug("PORT: mainWindow ok");
|
||
|
mainWindow->resize(680, 500);
|
||
|
arts_debug("PORT: mainWindow show");
|
||
|
mainWindow->show();
|
||
|
arts_debug("PORT: mainWindow show ok");
|
||
|
|
||
|
#if 0 /* PORT */
|
||
|
ArtsCorba::ModuleBroker_var ModuleBroker = theSynthesizer->moduleBroker();
|
||
|
assert(ModuleBroker);
|
||
|
#endif
|
||
|
|
||
|
setTopWidget(mainWindow);
|
||
|
}
|
||
|
|
||
|
void ArtsBuilderApp::end()
|
||
|
{
|
||
|
delete mainWindow;
|
||
|
}
|
||
|
|
||
|
/*************************************************************/
|
||
|
|
||
|
static KCmdLineOptions options[] =
|
||
|
{
|
||
|
{ "+[file]", I18N_NOOP("Optional .arts file to be loaded"), 0 },
|
||
|
KCmdLineLastOption
|
||
|
};
|
||
|
|
||
|
#ifdef COMMON_BINARY
|
||
|
int artsbuilder_main(int argc, char **argv)
|
||
|
#else
|
||
|
int main(int argc, char **argv)
|
||
|
#endif
|
||
|
{
|
||
|
KAboutData aboutData("artsbuilder",
|
||
|
I18N_NOOP("artsbuilder"),
|
||
|
ARTS_VERSION,
|
||
|
I18N_NOOP("aRts synthesizer designer"),
|
||
|
KAboutData::License_GPL,
|
||
|
"(C) 1998-2001, Stefan Westerfeld",
|
||
|
I18N_NOOP("The analog real-time synthesizer graphical design tool."),
|
||
|
"http://www.arts-project.org/",
|
||
|
"submit@bugs.kde.org");
|
||
|
|
||
|
aboutData.addAuthor("Stefan Westerfeld", I18N_NOOP("Author"), "stefan@twc.de");
|
||
|
aboutData.addCredit("Waldo Bastian", 0, "bastian@kde.org");
|
||
|
aboutData.addCredit("Jens Hahn", 0, "Jens.Hahn@t-online.de");
|
||
|
aboutData.addCredit("Martin Lorenz", 0, "lorenz@ch.tum.de");
|
||
|
aboutData.addCredit("Hans Meine", 0, "hans_meine@gmx.net");
|
||
|
aboutData.addCredit("Jeff Tranter", 0, "tranter@pobox.com");
|
||
|
|
||
|
KCmdLineArgs::init(argc, argv, &aboutData);
|
||
|
KCmdLineArgs::addCmdLineOptions(options);
|
||
|
Arts::QIOManager iomanager;
|
||
|
Arts::Dispatcher dispatcher(&iomanager);
|
||
|
|
||
|
Arts::ObjectManager::the()->provideCapability("kdegui");
|
||
|
|
||
|
// check for one optional filename argument
|
||
|
KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
|
||
|
if(args->count() > 1) {
|
||
|
args->usage("");
|
||
|
}
|
||
|
if(args->count() > 0)
|
||
|
{
|
||
|
ArtsBuilderApp Application(QFile::decodeName(args->arg(0)));
|
||
|
args->clear();
|
||
|
return Application.exec();
|
||
|
} else {
|
||
|
ArtsBuilderApp Application;
|
||
|
args->clear();
|
||
|
return Application.exec();
|
||
|
}
|
||
|
}
|
||
|
#include "main.moc"
|