summaryrefslogtreecommitdiffstats
path: root/arts/builder/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'arts/builder/main.cpp')
-rw-r--r--arts/builder/main.cpp958
1 files changed, 958 insertions, 0 deletions
diff --git a/arts/builder/main.cpp b/arts/builder/main.cpp
new file mode 100644
index 00000000..9c6d4277
--- /dev/null
+++ b/arts/builder/main.cpp
@@ -0,0 +1,958 @@
+/*
+
+ 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"