diff options
Diffstat (limited to 'kmid')
84 files changed, 10324 insertions, 0 deletions
diff --git a/kmid/ChangeLog b/kmid/ChangeLog new file mode 100644 index 00000000..6914c1d0 --- /dev/null +++ b/kmid/ChangeLog @@ -0,0 +1,104 @@ +0.1 30-10-97 +----- -------- +First version + +0.2 9-11-97 +----- ------- +Better syncronization between lyrics and music. +Drag&Drop, better installation, icons, Customizable fonts. + +0.3 16-11-97 +----- -------- +The lyrics handler is very improved. +Option to automagically select lyrics or text. +Better handling for broken files. +Few bug fixes. +Real Session Management. +First rpm version. + +0.4 30-12-97 +----- -------- +Fixed the pthread bug (sorry to everyone that suffered it ;-)) +Added support for AWE and GUS cards +Can modify the midi device without recompiling. +Can play gzipped files + +0.41 22-2-98 +----- ------- +Fixed a problem with GUS cards +Improved midi mapper +Fixed a non-feature :-) related to FM +New icon and toolbar pixmaps which use fewer colors + +0.5 15-3-98 +----- ------- +FM support +Playlists (Collections) +Some small improvements here and there + +0.5.1 15-3-98 +----- ------- +A very small bug fix + +0.5.2 5-4-98 +----- ------ +Save Lyrics +Some bug fixes +More keys binded to functions (arrows, space, backspace, etc.) + +0.5.3 24-4-98 +----- ------- +Improved Synchronization between gui and player +Some bug fixes: + - One which caused kmid to freeze when playing a collection with only 1 song + in aleatory mode and changing to next song + (reported by Jose Luis Sanchez) + - It was not possible to play a gzipped file that have spaces in its name + - There were some songs that played at a lower volume when moving the + slider, but not if playing from the beginning. +Better support for shuffle mode (now it doesn't repeat songs :-)) + +0.6 7-5-98 +----- ------ +Just thought that everything worked fine and did a major release to +put it in my homepage + +1.0 22-6-98 +----- ------- +Well, I should be studying, but KDE 1.0 good deserves a few minutes +to change the version number everywhere, remove debug printfs, and +clean the latest bugs, isn't it ? :-) + +1.2 14-9-98 +----- ------- +This version includes a new ChannelView to see notes played by each +instrument and a volume bar. +It also has some bug fixes and support for really broken midi files. + +1.6 27-11-98 +----- -------- +This version fix a bug that made kmid totally unusable to many users +because it played music at different tempos (sometimes faster and +sometimes slower), without any rhythm. Anyway, this isn't a public +version yet, it's only available from CVS. + +1.7 2-4-99 +----- ------- +Modified KMid to work with Linux kernels from the 2.2.x series which +work very different than the ones in 2.0.x . That problem made KMid +continue playing music for a while (up to a few minutes !) after the +user had pressed the stop button. +Fixed a problem with AWE cards that made it play files with the pitch +bender raised. +Fixed a problem that made kmid not to play the last few milliseconds of +some songs (sometimes up to half a second) +Another usual fixes (better support for kernel modules, workarounds for +compiler bugs, etc.) + +2.0 1-10-2000 +----- --------- +KMid has been ported to KDE 2.0 +Now has a separated ui and engine, it also has native ALSA support +It's a part now, so you can embed KMid in Konqueror and other apps. +Ah, and the scroll is smooth now :) + diff --git a/kmid/Makefile.am b/kmid/Makefile.am new file mode 100644 index 00000000..6dd4acb7 --- /dev/null +++ b/kmid/Makefile.am @@ -0,0 +1,74 @@ +INCLUDES = $(all_includes) + +kde_module_LTLIBRARIES = libkmidpart.la +lib_LTLIBRARIES = libkmidlib.la + +libkmidlib_la_LDFLAGS = $(all_libraries) +libkmidlib_la_LIBADD = $(LIB_KFILE) $(LIB_KPARTS) $(LIB_KIO) -lkmid + +libkmidpart_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) -module +libkmidpart_la_LIBADD = libkmidlib.la + +libkmidlib_la_SOURCES = kmidframe.cpp kmidclient.cpp kdisptext.cpp \ + qslidertime.cpp klcdnumber.cpp ktrianglebutton.cpp \ + midicfgdlg.cpp collectdlg.cpp randomlist.cpp \ + channelview.cpp channel.cpp channel3d.cpp channel4d.cpp \ + channelcfgdlg.cpp instrname.cpp rhythmview.cpp \ + songlist.cpp slman.cpp kmid_part.cpp kmidIface.skel + +libkmidpart_la_SOURCES = part_dummy.cpp + +part_dummy.cpp: + touch part_dummy.cpp + +noinst_HEADERS = kmidframe.h kmidclient.h kdisptext.h \ + qslidertime.h klcdnumber.h ktrianglebutton.h \ + midicfgdlg.h collectdlg.h randomlist.h \ + channelview.h channel.h channel3d.h channel4d.h \ + channelcfgdlg.h instrname.h rhythmview.h \ + songlist.h slman.h kmid_part.h + +kmid_LDFLAGS = $(all_libraries) $(KDE_RPATH) +kmid_SOURCES = main.cpp +kmid_LDADD = libkmidlib.la + +bin_PROGRAMS = kmid +METASOURCES = AUTO + +servicetype_DATA = audiomidi.desktop +servicetypedir = $(kde_servicetypesdir) + +SUBDIRS = maps examples pics + +xdg_apps_DATA = kmid.desktop + +mime_DATA = x-karaoke.desktop +mimedir = $(kde_mimedir)/audio + +rc_DATA = kmidui.rc +rcdir = $(kde_datadir)/kmid + +KDE_ICON = kmid + +fmpatches_DATA = std.sb drums.sb std.o3 drums.o3 +fmpatchesdir = $(kde_datadir)/kmid/fm + +partdir = $(kde_datadir)/kmid +part_DATA = kmid_partui.rc + +channelview_DATA = keyboard.xpm button1.xpm button2.xpm +channelviewdir = $(kde_datadir)/kmid/icons + +EXTRA_DIST = $(xdg_apps_DATA) $(mime_DATA) $(fmpatches_DATA) $(part_DATA) + +instrname.i18n: instrname.cpp + echo "/* This is an automatically generated file" > instrname.i18n + echo " * DO NOT EDIT !!!" >> instrname.i18n + echo " * To create this file run : ""make instrname.i18n"" " >> instrname.i18n + echo " */" >> instrname.i18n + echo "" >> instrname.i18n + awk -f instrfilter.awk instrname.cpp >> instrname.i18n + + +messages: instrname.i18n rc.cpp + $(XGETTEXT) *.cpp instrname.i18n -o $(podir)/kmid.pot diff --git a/kmid/PEOPLE b/kmid/PEOPLE new file mode 100644 index 00000000..4cd777c2 --- /dev/null +++ b/kmid/PEOPLE @@ -0,0 +1,4 @@ +Please take a look at the online help for a list of people who have helped +me in the development of KMid (emotionally or with patches :-) ). + + - Antonio Larrosa diff --git a/kmid/README b/kmid/README new file mode 100644 index 00000000..52c5f759 --- /dev/null +++ b/kmid/README @@ -0,0 +1,123 @@ +********************************************************************** + KKK KK MMM MMM IIIIII DDDDD + KKK KK MMMMMMMMMM IIII DDDDDDD + KKKKK MMMMMMMMMM II DDD DD + Console KKKKKK MMM MM MMM IIII DDDDDDD + KKK KKK MMM MMM IIIIII DDDDD + + ConsoleKMID + + + This info is up to date if you have KMid version 1.7 + +________________________________________________ +If you are looking for a KMid README file, then this is NOT the one you are +looking for. Please look the online documentation, that is, the html help + +I've left this file only for help on the small cousin of KMid, ConsoleKMid. + + - Antonio Larrosa +------------------------------------------------ + +Index +------- + 1. What is ConsoleKMid ? + 2. Requirements of consoleKMid + 3. Compiling consoleKMid + 4. Installing + 5. Running + 6. How do I use a Midi Mapper ? + 7. Where can I download KMid and consoleKMid from ? + 8. To do list + +1. What is ConsoleKMid ? +------------------------ + ConsoleKMid is a small program for Unix in console mode, which uses the same + player engine of KMid. Of course it doesn't have the same friendly + interface of KMid but it works to play midi files. + + If you have the rpm distribution, you will not find the consolekmid program + unless you have compiled it from the src.rpm distribution + + +2. Requirements of consoleKMid +------------------------------- + + A UNIX machine, a soundcard and a /dev/sequencer device well installed. + If you have a GUS, you need a properly installed driver from the Linux + Ultrasound Project, AWE cards are also supported, but you will probably + need to compile consoleKMid in order to get an AWE card to work. + FM devices are also supported. + I have only tested KMid in Linux, but I have had sucessful reports getting + KMid to work on FreeBSD + If you sucessfully run KMid in other unices, please tell me ! + + Currently GUS cards make a little sound when using the oss driver, but are + not supported officially, I'm looking to find people with GUS cards that + want to help me to provide such support (either programming or testing), + as I think that if nobody has worried about it it's because there's no + need for it ;-) + +3. Compiling consoleKMid +----------------- + Do a configure from the parent directory, then go to the player directory, + and do a 'make' . Simple , isn't it ? + + By default it will use the external midi device, if you want to use another + one (fm, awe, or anything else), edit the file main.cc and change the value + of DEFAULT_DEVICE to the one you want, or specify the -d option as in : + + consolekmid -d 1 mymidifile.mid + +4. Installing +----------------- + No installing of consoleKMid is actually done, just copy the consoleKMid file + yourself to where you want (usually /usr/local/bin ). To use the fm device, + you should specify in fmout.cc the path to where the fm patches are installed + ( /etc by default) + +5. Running +-------------- + Well, it's quite easy, just type "consolekmid" and it should run :-) + +6. How do I use a Midi Mapper ? +------------------------------- + A Midi Mapper is the feature you have been waiting for in Linux for years, + (at least I have been :-) it makes a non General Midi synth, appear to the + computer as General Midi compliant. Thus, a GM synth is emulated with a + nonGM. + Look the KMid docs for more info on creating/using a midi map. + If you want to use one with consolekmid, you can use the -M option, + use it like this example : + + consolekmid -M /opt/kde/share/apps/kmid/maps/YamahaPSS790.map mymidifile + + You can also edit main.cc in the player directory and change the value of + DEFAULT_MAP to whatever you want, so that you don't need to specify the + -M option each time you run consolekmid. + + If you want to define a new map for your midi keyboard, I recommend you to + start by copying the file yamaha790.map and modifying it. And remember to + send it to me so that it will be included in future revisions and other + people can use it ! + +7. Where can I download KMid and consoleKMid from ? +--------------------------------------------------- + + KMid's homepage is at : + http://developer.kde.org/~larrosa/kmid.html + + From there you can download latest versions as well as know the latest + changes and improvements of KMid and consoleKMid + +8. To do list +--------------- + GUS support is nearly done (and also SoftOSS) but still need little + improvements. It should mostly work now. + Better AWE support and use Soundfonts + The KMidServer and make KMid use it. + +------- +30-4-2001 +Antonio Larrosa Jimenez +larrosa@kde.org diff --git a/kmid/audiomidi.desktop b/kmid/audiomidi.desktop new file mode 100644 index 00000000..420045bf --- /dev/null +++ b/kmid/audiomidi.desktop @@ -0,0 +1,3 @@ +# This file used to define audio/x-midi, which is already defined as a mime type! +[Desktop Entry] +Hidden=true diff --git a/kmid/button1.xpm b/kmid/button1.xpm new file mode 100644 index 00000000..93d38a73 --- /dev/null +++ b/kmid/button1.xpm @@ -0,0 +1,22 @@ +/* XPM */ +static char * button1_xpm[] = { +"16 16 3 1", +" c None", +". c #000000000000", +"X c #FFFF00000000", +" ", +" .... ", +" ........ ", +" .......... ", +" .....XX..... ", +" ...XXXXXX... ", +" ....XXXXXX.... ", +" ...XXXXXXXX... ", +" ...XXXXXXXX... ", +" ....XXXXXX.... ", +" ...XXXXXX... ", +" .....XX..... ", +" .......... ", +" ........ ", +" .... ", +" "}; diff --git a/kmid/button2.xpm b/kmid/button2.xpm new file mode 100644 index 00000000..8c8922df --- /dev/null +++ b/kmid/button2.xpm @@ -0,0 +1,22 @@ +/* XPM */ +static char * button2_xpm[] = { +"16 16 3 1", +" c None", +". c #000000000000", +"X c #0000FFFF0000", +" ", +" .... ", +" ........ ", +" .......... ", +" .....XX..... ", +" ...XXXXXX... ", +" ....XXXXXX.... ", +" ...XXXXXXXX... ", +" ...XXXXXXXX... ", +" ....XXXXXX.... ", +" ...XXXXXX... ", +" .....XX..... ", +" .......... ", +" ........ ", +" .... ", +" "}; diff --git a/kmid/channel.cpp b/kmid/channel.cpp new file mode 100644 index 00000000..14dd95a9 --- /dev/null +++ b/kmid/channel.cpp @@ -0,0 +1,233 @@ +/************************************************************************** + + channel.cpp - The KMidChannel widget (with pure virtual members) + Copyright (C) 1998 Antonio Larrosa Jimenez + + 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. + + Send comments and bug fixes to larrosa@kde.org + or to Antonio Larrosa, Rio Arnoya, 10 5B, 29006 Malaga, Spain + +***************************************************************************/ + +#include <stdio.h> +#include <stdlib.h> + +#include <qpainter.h> +#include <qcombobox.h> + +#include <kglobal.h> +#include <kinstance.h> +#include <kconfig.h> +#include <klocale.h> +#include <kstandarddirs.h> +#include "kmidbutton.h" + +#include "channel.h" +#include "instrname.h" +#include <kiconloader.h> + +KMidChannel::KMidChannel(int chn,QWidget *parent) : QWidget (parent) +{ + channel=chn; + replay=TRUE; + int i; + for (i=0;i<128;i++) pressed[i]=0; + keyboard = QPixmap(locate("appdata","icons/keyboard.xpm")); + penB = new QPen (black); + penW = new QPen (white); + penT = new QPen (colorGroup().background()); + + KConfig *kcfg=KGlobal::instance()->config(); + kcfg->setGroup("KMid"); + QFont *qtextfontdefault=new QFont("lucida",18,QFont::Bold,TRUE); + qcvfont=new QFont(kcfg->readFontEntry("ChannelViewFont",qtextfontdefault)); + delete qtextfontdefault; + + instrumentCombo = new QComboBox(FALSE,this,"instr"); + instrumentCombo->setGeometry(160,2,200,20); + + for (i=0;i<128;i++) + instrumentCombo->insertItem(i18n(instrumentName[i]),i); + + connect(instrumentCombo,SIGNAL(activated(int)),this,SLOT(pgmChanged(int))); + + forcepgm=new KMidButton(this,"forcepgm"); + forcepgm->setGeometry(135,4,16,16); + forcepgm->setToggleButton(TRUE); + button1 = QPixmap(locate("appdata","icons/button1.xpm")); + button2 = QPixmap(locate("appdata","icons/button2.xpm")); + forcepgm->setPixmaps(button1,button2); + forcepgm->show(); + connect(forcepgm,SIGNAL(toggled(bool)),this,SLOT(changeForcedState(bool))); + +} + +KMidChannel::~KMidChannel() +{ + delete penB; + delete penW; + delete penT; +} + +void KMidChannel::paintEvent( QPaintEvent * ) +{ + + QPainter *qpaint=new QPainter(this); + + QString tmp = i18n("Channel %1").arg(channel); + qpaint->setFont(*qcvfont); + qpaint->setPen(*penB); + qpaint->drawText(2,20,tmp); + qpaint->setPen(*penW); + qpaint->drawText(0,18,tmp); + + drawKeyboard(qpaint); + drawPressedKeys(qpaint); + + delete qpaint; +} + +void KMidChannel::drawKeyboard(QPainter *qpaint) +{ + int x=1; + for (int i=0;(i<12) && (x<width());i++,x+=63) + { + qpaint->drawPixmap(x,KEYBOARDY,keyboard); + }; + qpaint->setPen(*penB); + qpaint->drawLine(0,KEYBOARDY,0,KEYBOARDY+44); + + qpaint->setPen(*penT); + qpaint->drawLine(0,KEYBOARDY+45,x+63,KEYBOARDY+45); + + +} + +void KMidChannel::drawPressedKeys(QPainter *qpaint) +{ + for (int i=0;i<128;i++) + if (pressed[i]) drawKey(qpaint,i); +} + +void KMidChannel::drawKey(QPainter *qpaint,int key) +{ + int octave=key/12; + int note=key%12; + int x=octave*63+1; + + switch (note) + { + case (0) : drawDo (qpaint,x,pressed[key]);break; + case (1) : drawDo__ (qpaint,x,pressed[key]);break; + case (2) : drawRe (qpaint,x,pressed[key]);break; + case (3) : drawRe__ (qpaint,x,pressed[key]);break; + case (4) : drawMi (qpaint,x,pressed[key]);break; + case (5) : drawFa (qpaint,x,pressed[key]);break; + case (6) : drawFa__ (qpaint,x,pressed[key]);break; + case (7) : drawSol (qpaint,x,pressed[key]);break; + case (8) : drawSol__(qpaint,x,pressed[key]);break; + case (9) : drawLa (qpaint,x,pressed[key]);break; + case (10) : drawLa__ (qpaint,x,pressed[key]);break; + case (11) : drawSi (qpaint,x,pressed[key]);break; + }; +// qpaint->flush(); +} + +void KMidChannel::noteOn(int key) +{ + pressed[key]=1; + QPainter *qpaint=new QPainter(this); + drawKey(qpaint,key); + delete qpaint; +} + +void KMidChannel::noteOff(int key) +{ + pressed[key]=0; + QPainter *qpaint=new QPainter(this); + drawKey(qpaint,key); + delete qpaint; +} + +void KMidChannel::changeInstrument(int pgm) +{ + instrumentCombo->setCurrentItem(pgm); +} + +void KMidChannel::changeForceState(bool i) +{ + replay=FALSE; + forcepgm->setOn(i); + replay=TRUE; +} + +void KMidChannel::reset(int level) +{ + for (int i=0;i<128;i++) pressed[i]=0; + if (level>=1) + { + instrumentCombo->setCurrentItem(0); + replay=FALSE; + forcepgm->setOn(FALSE); + replay=TRUE; + }; + + repaint(FALSE); +} + +void KMidChannel::saveState(bool *p,int *pgm) +{ + for (int i=0;i<128;i++) p[i]=pressed[i]; + *pgm=instrumentCombo->currentItem(); +} + +void KMidChannel::loadState(bool *p,int *pgm) +{ + for (int i=0;i<128;i++) pressed[i]=p[i]; + instrumentCombo->setCurrentItem(*pgm); + repaint(FALSE); +} + +void KMidChannel::pgmChanged(int i) +{ + int data[4]; + data[0]=CHN_CHANGE_PGM; + data[1]=channel; + data[2]=i; + data[3]=0; + + replay=FALSE; + forcepgm->setOn(TRUE); + replay=TRUE; + + emit signalToKMidClient(data); + + +} + + +void KMidChannel::changeForcedState(bool i) +{ + int data[4]; + data[0]=CHN_CHANGE_FORCED_STATE; + data[1]=channel; + data[2]=i; + data[3]=(replay)? 1 : 0; + + emit signalToKMidClient(data); + +} +#include "channel.moc" diff --git a/kmid/channel.h b/kmid/channel.h new file mode 100644 index 00000000..29ddfcd2 --- /dev/null +++ b/kmid/channel.h @@ -0,0 +1,104 @@ +/************************************************************************** + + channel.h - The KMidChannel widget (with pure virtual members) + Copyright (C) 1998 Antonio Larrosa Jimenez + + 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. + + Send comments and bug fixes to larrosa@kde.org + or to Antonio Larrosa, Rio Arnoya, 10 5B, 29006 Malaga, Spain + +***************************************************************************/ + +#ifndef KMIDCHANNEL_H +#define KMIDCHANNEL_H +#include <qwidget.h> +#include <qpixmap.h> + +#define CHANNELHEIGHT 71 +#define KEYBOARDY CHANNELHEIGHT-46 + +#define CHN_CHANGE_PGM 1 +#define CHN_CHANGE_FORCED_STATE 2 + +class QFont; +class QComboBox; +class KMidButton; +class KMidChannel : public QWidget +{ + Q_OBJECT + +private: + bool pressed[128]; // The 128 keys + int channel; + bool replay; // Indicates if music should restart playing after + // changing the force state + +protected: + QPixmap keyboard; + QPixmap button1; + QPixmap button2; + + QComboBox *instrumentCombo; + + KMidButton *forcepgm; + QFont *qcvfont; + + QPen *penB; // Black + QPen *penW; // White + QPen *penT; // "Transparent" for Background + + void paintEvent( QPaintEvent * ); +public: + KMidChannel(int i,QWidget *Parent); + virtual ~KMidChannel(); + + void drawKeyboard(QPainter *qpaint); + void drawPressedKeys(QPainter *qpaint); + void drawKey(QPainter *qpaint,int key); + + virtual void drawDo (QPainter *qpaint,int x,int p) = 0; + virtual void drawDo__ (QPainter *qpaint,int x,int p) = 0; + virtual void drawRe (QPainter *qpaint,int x,int p) = 0; + virtual void drawRe__ (QPainter *qpaint,int x,int p) = 0; + virtual void drawMi (QPainter *qpaint,int x,int p) = 0; + virtual void drawFa (QPainter *qpaint,int x,int p) = 0; + virtual void drawFa__ (QPainter *qpaint,int x,int p) = 0; + virtual void drawSol (QPainter *qpaint,int x,int p) = 0; + virtual void drawSol__(QPainter *qpaint,int x,int p) = 0; + virtual void drawLa (QPainter *qpaint,int x,int p) = 0; + virtual void drawLa__ (QPainter *qpaint,int x,int p) = 0; + virtual void drawSi (QPainter *qpaint,int x,int p) = 0; + + void noteOn(int key); + void noteOff(int key); + void changeInstrument(int pgm); + void changeForceState(bool i); + + void reset(int level=1); // 0 only release notes, 1 also set instr to 0 ... + + void saveState(bool *p,int *pgm); + void loadState(bool *p,int *pgm); + +public slots: + void pgmChanged(int i); + void changeForcedState(bool); + +signals: + void signalToKMidClient(int *data); + +}; + +#endif diff --git a/kmid/channel3d.cpp b/kmid/channel3d.cpp new file mode 100644 index 00000000..2a2451c6 --- /dev/null +++ b/kmid/channel3d.cpp @@ -0,0 +1,149 @@ +/************************************************************************** + + channel3d.cpp - KMidChannel3D widget, a Channel widget with 3D look + Copyright (C) 1998 Antonio Larrosa Jimenez + + 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. + + Send comments and bug fixes to larrosa@kde.org + or to Antonio Larrosa, Rio Arnoya, 10 5B, 29006 Malaga, Spain + +***************************************************************************/ + +#include "channel3d.h" +#include <qpainter.h> + +KMidChannel3D::KMidChannel3D (int chn,QWidget *parent) : KMidChannel(chn,parent) +{ +} + +void KMidChannel3D::drawDo(QPainter *qpaint,int x,int p) +{ + qpaint->setPen(p?(*penW):(*penB)); + qpaint->drawLine(x,KEYBOARDY+43,x+6,KEYBOARDY+43); + qpaint->drawLine(x,KEYBOARDY+44,x+6,KEYBOARDY+44); + qpaint->setPen(p?(*penB):(*penT)); + qpaint->drawLine(x-1,KEYBOARDY+45,x+8,KEYBOARDY+45); + qpaint->setPen(p?(*penB):(*penW)); + qpaint->drawLine(x+7,KEYBOARDY+28,x+7,KEYBOARDY+42); +} +void KMidChannel3D::drawDo__(QPainter *qpaint,int x,int p) +{ + qpaint->setPen(p?(*penB):(*penW)); + qpaint->drawLine(x+6,KEYBOARDY+2,x+6,KEYBOARDY+25); + qpaint->drawLine(x+7,KEYBOARDY+25,x+11,KEYBOARDY+25); + + qpaint->setPen(p?(*penW):(*penB)); + qpaint->drawLine(x+11,KEYBOARDY+1,x+11,KEYBOARDY+27); + qpaint->drawPoint(x+10,KEYBOARDY+27); + +} +void KMidChannel3D::drawRe(QPainter *qpaint,int x,int p) +{ + qpaint->setPen(p?(*penW):(*penB)); + qpaint->drawLine(x+9,KEYBOARDY+43,x+15,KEYBOARDY+43); + qpaint->drawLine(x+9,KEYBOARDY+44,x+15,KEYBOARDY+44); + qpaint->setPen(p?(*penB):(*penT)); + qpaint->drawLine(x+8,KEYBOARDY+45,x+17,KEYBOARDY+45); + qpaint->setPen(p?(*penB):(*penW)); + qpaint->drawLine(x+16,KEYBOARDY+28,x+16,KEYBOARDY+42); +} +void KMidChannel3D::drawRe__(QPainter *qpaint,int x,int p) +{ + qpaint->setPen(p?(*penB):(*penW)); + qpaint->drawLine(x+15,KEYBOARDY+2,x+15,KEYBOARDY+25); + qpaint->drawLine(x+16,KEYBOARDY+25,x+20,KEYBOARDY+25); + + qpaint->setPen(p?(*penW):(*penB)); + qpaint->drawLine(x+20,KEYBOARDY+1,x+20,KEYBOARDY+27); + qpaint->drawPoint(x+19,KEYBOARDY+27); +} +void KMidChannel3D::drawMi(QPainter *qpaint,int x,int p) +{ + qpaint->setPen(p?(*penW):(*penB)); + qpaint->drawLine(x+18,KEYBOARDY+43,x+24,KEYBOARDY+43); + qpaint->drawLine(x+18,KEYBOARDY+44,x+24,KEYBOARDY+44); + qpaint->setPen(p?(*penB):(*penT)); + qpaint->drawLine(x+17,KEYBOARDY+45,x+26,KEYBOARDY+45); + qpaint->setPen(p?(*penB):(*penW)); + qpaint->drawLine(x+25,KEYBOARDY+1,x+25,KEYBOARDY+42); +} +void KMidChannel3D::drawFa(QPainter *qpaint,int x,int p) +{ + qpaint->setPen(p?(*penW):(*penB)); + qpaint->drawLine(x+27,KEYBOARDY+43,x+33,KEYBOARDY+43); + qpaint->drawLine(x+27,KEYBOARDY+44,x+33,KEYBOARDY+44); + qpaint->setPen(p?(*penB):(*penT)); + qpaint->drawLine(x+26,KEYBOARDY+45,x+35,KEYBOARDY+45); + qpaint->setPen(p?(*penB):(*penW)); + qpaint->drawLine(x+34,KEYBOARDY+28,x+34,KEYBOARDY+42); +} +void KMidChannel3D::drawFa__(QPainter *qpaint,int x,int p) +{ + qpaint->setPen(p?(*penB):(*penW)); + qpaint->drawLine(x+33,KEYBOARDY+2,x+33,KEYBOARDY+25); + qpaint->drawLine(x+34,KEYBOARDY+25,x+38,KEYBOARDY+25); + qpaint->setPen(p?(*penW):(*penB)); + qpaint->drawLine(x+38,KEYBOARDY+1,x+38,KEYBOARDY+27); + qpaint->drawPoint(x+37,KEYBOARDY+27); +} +void KMidChannel3D::drawSol(QPainter *qpaint,int x,int p) +{ + qpaint->setPen(p?(*penW):(*penB)); + qpaint->drawLine(x+36,KEYBOARDY+43,x+42,KEYBOARDY+43); + qpaint->drawLine(x+36,KEYBOARDY+44,x+42,KEYBOARDY+44); + qpaint->setPen(p?(*penB):(*penT)); + qpaint->drawLine(x+35,KEYBOARDY+45,x+44,KEYBOARDY+45); + qpaint->setPen(p?(*penB):(*penW)); + qpaint->drawLine(x+43,KEYBOARDY+28,x+43,KEYBOARDY+42); +} +void KMidChannel3D::drawSol__(QPainter *qpaint,int x,int p) +{ + qpaint->setPen(p?(*penB):(*penW)); + qpaint->drawLine(x+42,KEYBOARDY+2,x+42,KEYBOARDY+25); + qpaint->drawLine(x+43,KEYBOARDY+25,x+47,KEYBOARDY+25); + qpaint->setPen(p?(*penW):(*penB)); + qpaint->drawLine(x+47,KEYBOARDY+1,x+47,KEYBOARDY+27); + qpaint->drawPoint(x+46,KEYBOARDY+27); +} +void KMidChannel3D::drawLa(QPainter *qpaint,int x,int p) +{ + qpaint->setPen(p?(*penW):(*penB)); + qpaint->drawLine(x+45,KEYBOARDY+43,x+51,KEYBOARDY+43); + qpaint->drawLine(x+45,KEYBOARDY+44,x+51,KEYBOARDY+44); + qpaint->setPen(p?(*penB):(*penT)); + qpaint->drawLine(x+44,KEYBOARDY+45,x+53,KEYBOARDY+45); + qpaint->setPen(p?(*penB):(*penW)); + qpaint->drawLine(x+52,KEYBOARDY+28,x+52,KEYBOARDY+42); +} +void KMidChannel3D::drawLa__(QPainter *qpaint,int x,int p) +{ + qpaint->setPen(p?(*penB):(*penW)); + qpaint->drawLine(x+51,KEYBOARDY+2,x+51,KEYBOARDY+25); + qpaint->drawLine(x+52,KEYBOARDY+25,x+56,KEYBOARDY+25); + qpaint->setPen(p?(*penW):(*penB)); + qpaint->drawLine(x+56,KEYBOARDY+1,x+56,KEYBOARDY+27); + qpaint->drawPoint(x+55,KEYBOARDY+27); +} +void KMidChannel3D::drawSi(QPainter *qpaint,int x,int p) +{ + qpaint->setPen(p?(*penW):(*penB)); + qpaint->drawLine(x+54,KEYBOARDY+43,x+60,KEYBOARDY+43); + qpaint->drawLine(x+54,KEYBOARDY+44,x+60,KEYBOARDY+44); + qpaint->setPen(p?(*penB):(*penT)); + qpaint->drawLine(x+53,KEYBOARDY+45,x+62,KEYBOARDY+45); + qpaint->setPen(p?(*penB):(*penW)); + qpaint->drawLine(x+61,KEYBOARDY+1,x+61,KEYBOARDY+42); +} diff --git a/kmid/channel3d.h b/kmid/channel3d.h new file mode 100644 index 00000000..e0bfcc67 --- /dev/null +++ b/kmid/channel3d.h @@ -0,0 +1,52 @@ +/************************************************************************** + + channel3d.h - KMidChannel3D widget, a Channel widget with 3D look + Copyright (C) 1998 Antonio Larrosa Jimenez + + 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. + + Send comments and bug fixes to larrosa@kde.org + or to Antonio Larrosa, Rio Arnoya, 10 5B, 29006 Malaga, Spain + +***************************************************************************/ + +#ifndef KMIDCHANNEL3D_H +#define KMIDCHANNEL3D_H + +#include "channel.h" + +class KMidChannel3D : public KMidChannel +{ +public: + KMidChannel3D(int chn,QWidget *parent); + + + virtual void drawDo (QPainter *qpaint,int x,int p); + virtual void drawDo__ (QPainter *qpaint,int x,int p); + virtual void drawRe (QPainter *qpaint,int x,int p); + virtual void drawRe__ (QPainter *qpaint,int x,int p); + virtual void drawMi (QPainter *qpaint,int x,int p); + virtual void drawFa (QPainter *qpaint,int x,int p); + virtual void drawFa__ (QPainter *qpaint,int x,int p); + virtual void drawSol (QPainter *qpaint,int x,int p); + virtual void drawSol__(QPainter *qpaint,int x,int p); + virtual void drawLa (QPainter *qpaint,int x,int p); + virtual void drawLa__ (QPainter *qpaint,int x,int p); + virtual void drawSi (QPainter *qpaint,int x,int p); + + +}; + +#endif diff --git a/kmid/channel4d.cpp b/kmid/channel4d.cpp new file mode 100644 index 00000000..a05cc5df --- /dev/null +++ b/kmid/channel4d.cpp @@ -0,0 +1,232 @@ +/************************************************************************** + + channel4d.cpp - KMidChannel4D widget, with 3D look and filled + Copyright (C) 1998 Antonio Larrosa Jimenez + + 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. + + Send comments and bug fixes to larrosa@kde.org + or to Antonio Larrosa, Rio Arnoya, 10 5B, 29006 Malaga, Spain + +***************************************************************************/ + +#include "channel4d.h" +#include <qpainter.h> + +KMidChannel4D::KMidChannel4D (int chn,QWidget *parent) : KMidChannel(chn,parent) +{ + brushR = new QBrush (red); + brushW = new QBrush (white); + brushB = new QBrush (black); + penR = new QPen (red); +} + + +void KMidChannel4D::drawDo(QPainter *qpaint,int x,int p) +{ + qpaint->setPen(p?(*penR):(*penB)); + + qpaint->drawLine(x,KEYBOARDY+43,x+6,KEYBOARDY+43); + qpaint->drawLine(x,KEYBOARDY+44,x+6,KEYBOARDY+44); + + qpaint->setPen(p?(*penB):(*penT)); + qpaint->drawLine(x-1,KEYBOARDY+45,x+8,KEYBOARDY+45); + qpaint->setPen(p?(*penB):(*penW)); + qpaint->drawLine(x+7,KEYBOARDY+28,x+7,KEYBOARDY+42); + + qpaint->fillRect(x,KEYBOARDY+28,7,15,((p)?*brushR:*brushW)); + qpaint->fillRect(x,KEYBOARDY+1,5,27,((p)?*brushR:*brushW)); + qpaint->setPen(p?(*penR):(*penW)); + qpaint->drawPoint(x+5,KEYBOARDY+27); +} +void KMidChannel4D::drawDo__(QPainter *qpaint,int x,int p) +{ + qpaint->fillRect(x+6,KEYBOARDY+1,5,26,((p)?*brushR:*brushB)); + + if (!p) + { + qpaint->setPen(*penW); + qpaint->drawLine(x+6,KEYBOARDY+2,x+6,KEYBOARDY+25); + qpaint->drawLine(x+7,KEYBOARDY+25,x+11,KEYBOARDY+25); + }; + + qpaint->setPen(p?(*penW):(*penB)); + qpaint->drawLine(x+11,KEYBOARDY+1,x+11,KEYBOARDY+27); + qpaint->drawPoint(x+10,KEYBOARDY+27); + + +} +void KMidChannel4D::drawRe(QPainter *qpaint,int x,int p) +{ + qpaint->setPen(p?(*penR):(*penB)); + qpaint->drawLine(x+9,KEYBOARDY+43,x+15,KEYBOARDY+43); + qpaint->drawLine(x+9,KEYBOARDY+44,x+15,KEYBOARDY+44); + qpaint->setPen(p?(*penB):(*penT)); + qpaint->drawLine(x+8,KEYBOARDY+45,x+17,KEYBOARDY+45); + qpaint->setPen(p?(*penB):(*penW)); + qpaint->drawLine(x+16,KEYBOARDY+28,x+16,KEYBOARDY+42); + + qpaint->fillRect(x+9,KEYBOARDY+28,7,15,((p)?*brushR:*brushW)); + qpaint->fillRect(x+12,KEYBOARDY+1,2,27,((p)?*brushR:*brushW)); + qpaint->setPen(p?(*penR):(*penW)); + qpaint->drawPoint(x+11,KEYBOARDY+27); + qpaint->drawPoint(x+14,KEYBOARDY+27); + +} + +void KMidChannel4D::drawRe__(QPainter *qpaint,int x,int p) +{ + qpaint->fillRect(x+15,KEYBOARDY+1,5,26,((p)?*brushR:*brushB)); + + if (!p) + { + qpaint->setPen(*penW); + qpaint->drawLine(x+15,KEYBOARDY+2,x+15,KEYBOARDY+25); + qpaint->drawLine(x+16,KEYBOARDY+25,x+20,KEYBOARDY+25); + }; + + qpaint->setPen(p?(*penW):(*penB)); + qpaint->drawLine(x+20,KEYBOARDY+1,x+20,KEYBOARDY+27); + qpaint->drawPoint(x+19,KEYBOARDY+27); + + +} +void KMidChannel4D::drawMi(QPainter *qpaint,int x,int p) +{ + qpaint->setPen(p?(*penR):(*penB)); + qpaint->drawLine(x+18,KEYBOARDY+43,x+24,KEYBOARDY+43); + qpaint->drawLine(x+18,KEYBOARDY+44,x+24,KEYBOARDY+44); + qpaint->setPen(p?(*penB):(*penT)); + qpaint->drawLine(x+17,KEYBOARDY+45,x+26,KEYBOARDY+45); + qpaint->setPen(p?(*penB):(*penW)); + qpaint->drawLine(x+25,KEYBOARDY+1,x+25,KEYBOARDY+42); + + qpaint->fillRect(x+18,KEYBOARDY+28,7,15,((p)?*brushR:*brushW)); + qpaint->fillRect(x+21,KEYBOARDY+1,4,27,((p)?*brushR:*brushW)); + qpaint->setPen(p?(*penR):(*penW)); + qpaint->drawPoint(x+20,KEYBOARDY+27); + +} +void KMidChannel4D::drawFa(QPainter *qpaint,int x,int p) +{ + qpaint->setPen(p?(*penR):(*penB)); + qpaint->drawLine(x+27,KEYBOARDY+43,x+33,KEYBOARDY+43); + qpaint->drawLine(x+27,KEYBOARDY+44,x+33,KEYBOARDY+44); + qpaint->setPen(p?(*penB):(*penT)); + qpaint->drawLine(x+26,KEYBOARDY+45,x+35,KEYBOARDY+45); + qpaint->setPen(p?(*penB):(*penW)); + qpaint->drawLine(x+34,KEYBOARDY+28,x+34,KEYBOARDY+42); + + qpaint->fillRect(x+27,KEYBOARDY+28,7,15,((p)?*brushR:*brushW)); + qpaint->fillRect(x+27,KEYBOARDY+1,5,27,((p)?*brushR:*brushW)); + qpaint->setPen(p?(*penR):(*penW)); + qpaint->drawPoint(x+32,KEYBOARDY+27); + +} +void KMidChannel4D::drawFa__(QPainter *qpaint,int x,int p) +{ + qpaint->fillRect(x+33,KEYBOARDY+1,5,26,((p)?*brushR:*brushB)); + if (!p) + { + qpaint->setPen(*penW); + qpaint->drawLine(x+33,KEYBOARDY+2,x+33,KEYBOARDY+25); + qpaint->drawLine(x+34,KEYBOARDY+25,x+38,KEYBOARDY+25); + }; + qpaint->setPen(p?(*penW):(*penB)); + qpaint->drawLine(x+38,KEYBOARDY+1,x+38,KEYBOARDY+27); + qpaint->drawPoint(x+37,KEYBOARDY+27); + +} + +void KMidChannel4D::drawSol(QPainter *qpaint,int x,int p) +{ + qpaint->setPen(p?(*penR):(*penB)); + qpaint->drawLine(x+36,KEYBOARDY+43,x+42,KEYBOARDY+43); + qpaint->drawLine(x+36,KEYBOARDY+44,x+42,KEYBOARDY+44); + qpaint->setPen(p?(*penB):(*penT)); + qpaint->drawLine(x+35,KEYBOARDY+45,x+44,KEYBOARDY+45); + qpaint->setPen(p?(*penB):(*penW)); + qpaint->drawLine(x+43,KEYBOARDY+28,x+43,KEYBOARDY+42); + + qpaint->fillRect(x+36,KEYBOARDY+28,7,15,((p)?*brushR:*brushW)); + qpaint->fillRect(x+39,KEYBOARDY+1,2,27,((p)?*brushR:*brushW)); + qpaint->setPen(p?(*penR):(*penW)); + qpaint->drawPoint(x+38,KEYBOARDY+27); + qpaint->drawPoint(x+41,KEYBOARDY+27); + +} + +void KMidChannel4D::drawSol__(QPainter *qpaint,int x,int p) +{ + qpaint->fillRect(x+42,KEYBOARDY+1,5,26,((p)?*brushR:*brushB)); + + if (!p) + { + qpaint->setPen(*penW); + qpaint->drawLine(x+42,KEYBOARDY+2,x+42,KEYBOARDY+25); + qpaint->drawLine(x+43,KEYBOARDY+25,x+47,KEYBOARDY+25); + }; + qpaint->setPen(p?(*penW):(*penB)); + qpaint->drawLine(x+47,KEYBOARDY+1,x+47,KEYBOARDY+27); + qpaint->drawPoint(x+46,KEYBOARDY+27); + + +} +void KMidChannel4D::drawLa(QPainter *qpaint,int x,int p) +{ + qpaint->setPen(p?(*penR):(*penB)); + qpaint->drawLine(x+45,KEYBOARDY+43,x+51,KEYBOARDY+43); + qpaint->drawLine(x+45,KEYBOARDY+44,x+51,KEYBOARDY+44); + qpaint->setPen(p?(*penB):(*penT)); + qpaint->drawLine(x+44,KEYBOARDY+45,x+53,KEYBOARDY+45); + qpaint->setPen(p?(*penB):(*penW)); + qpaint->drawLine(x+52,KEYBOARDY+28,x+52,KEYBOARDY+42); + + qpaint->fillRect(x+45,KEYBOARDY+28,7,15,((p)?*brushR:*brushW)); + qpaint->fillRect(x+48,KEYBOARDY+1,2,27,((p)?*brushR:*brushW)); + qpaint->setPen(p?(*penR):(*penW)); + qpaint->drawPoint(x+47,KEYBOARDY+27); + qpaint->drawPoint(x+50,KEYBOARDY+27); +} +void KMidChannel4D::drawLa__(QPainter *qpaint,int x,int p) +{ + qpaint->fillRect(x+51,KEYBOARDY+1,5,26,((p)?*brushR:*brushB)); + + if (!p) + { + qpaint->setPen(*penW); + qpaint->drawLine(x+51,KEYBOARDY+2,x+51,KEYBOARDY+25); + qpaint->drawLine(x+52,KEYBOARDY+25,x+56,KEYBOARDY+25); + }; + qpaint->setPen(p?(*penW):(*penB)); + qpaint->drawLine(x+56,KEYBOARDY+1,x+56,KEYBOARDY+27); + qpaint->drawPoint(x+55,KEYBOARDY+27); + +} +void KMidChannel4D::drawSi(QPainter *qpaint,int x,int p) +{ + qpaint->setPen(p?(*penR):(*penB)); + qpaint->drawLine(x+54,KEYBOARDY+43,x+60,KEYBOARDY+43); + qpaint->drawLine(x+54,KEYBOARDY+44,x+60,KEYBOARDY+44); + qpaint->setPen(p?(*penB):(*penT)); + qpaint->drawLine(x+53,KEYBOARDY+45,x+62,KEYBOARDY+45); + qpaint->setPen(p?(*penB):(*penW)); + qpaint->drawLine(x+61,KEYBOARDY+1,x+61,KEYBOARDY+42); + + qpaint->fillRect(x+54,KEYBOARDY+28,7,15,((p)?*brushR:*brushW)); + qpaint->fillRect(x+57,KEYBOARDY+1,4,27,((p)?*brushR:*brushW)); + qpaint->setPen(p?(*penR):(*penW)); + qpaint->drawPoint(x+56,KEYBOARDY+27); +} diff --git a/kmid/channel4d.h b/kmid/channel4d.h new file mode 100644 index 00000000..b97dc0e1 --- /dev/null +++ b/kmid/channel4d.h @@ -0,0 +1,58 @@ +/************************************************************************** + + channel4d.h - KMidChannel4D widget, with 3D look and filled + Copyright (C) 1998 Antonio Larrosa Jimenez + + 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. + + Send comments and bug fixes to larrosa@kde.org + or to Antonio Larrosa, Rio Arnoya, 10 5B, 29006 Malaga, Spain + +***************************************************************************/ + +#ifndef KMIDCHANNEL4D_H +#define KMIDCHANNEL4D_H + +#include "channel.h" + +class KMidChannel4D : public KMidChannel +{ +private: + QBrush *brushR; + QBrush *brushW; + QBrush *brushB; + QPen *penR; + +public: + KMidChannel4D(int chn,QWidget *parent); + + + virtual void drawDo (QPainter *qpaint,int x,int p); + virtual void drawDo__ (QPainter *qpaint,int x,int p); + virtual void drawRe (QPainter *qpaint,int x,int p); + virtual void drawRe__ (QPainter *qpaint,int x,int p); + virtual void drawMi (QPainter *qpaint,int x,int p); + virtual void drawFa (QPainter *qpaint,int x,int p); + virtual void drawFa__ (QPainter *qpaint,int x,int p); + virtual void drawSol (QPainter *qpaint,int x,int p); + virtual void drawSol__(QPainter *qpaint,int x,int p); + virtual void drawLa (QPainter *qpaint,int x,int p); + virtual void drawLa__ (QPainter *qpaint,int x,int p); + virtual void drawSi (QPainter *qpaint,int x,int p); + + +}; + +#endif diff --git a/kmid/channelcfgdlg.cpp b/kmid/channelcfgdlg.cpp new file mode 100644 index 00000000..8ed5ee66 --- /dev/null +++ b/kmid/channelcfgdlg.cpp @@ -0,0 +1,39 @@ +#include <qpushbutton.h> +#include <qbuttongroup.h> +#include <qradiobutton.h> +#include <kdialogbase.h> + +#include <kapplication.h> +#include <klocale.h> + +#include "channelview.h" +#include "channelcfgdlg.h" +#include "version.h" +#include <qlayout.h> +#include <qvbuttongroup.h> + +ChannelViewConfigDialog::ChannelViewConfigDialog(QWidget *parent,const char *name) : KDialogBase(parent,name,TRUE,i18n("Configure Channel View"),Ok|Cancel, Ok) +{ + QWidget *page = new QWidget( this ); + setMainWidget(page); + QVBoxLayout *topLayout = new QVBoxLayout( page, 0, spacingHint() ); + qbg = new QVButtonGroup(i18n("Choose Look Mode"),page,"qbg"); + + rb0=new QRadioButton(i18n("3D look"),qbg,"3d"); + rb1=new QRadioButton(i18n("3D - filled"),qbg,"4d"); + + qbg->setExclusive(TRUE); + + topLayout->addWidget( qbg ); + ((ChannelView::lookMode()==0)?rb0:rb1)->setChecked(TRUE); + + connect (qbg, SIGNAL(pressed(int)),this,SLOT(modeselected(int))); +} + +void ChannelViewConfigDialog::modeselected(int idx) +{ +selectedmode=idx; +} + +int ChannelViewConfigDialog::selectedmode; +#include "channelcfgdlg.moc" diff --git a/kmid/channelcfgdlg.h b/kmid/channelcfgdlg.h new file mode 100644 index 00000000..da7b7f82 --- /dev/null +++ b/kmid/channelcfgdlg.h @@ -0,0 +1,51 @@ +/************************************************************************** + + channelcfgdlg.h - The channel view config dialog + Copyright (C) 1998 Antonio Larrosa Jimenez + + 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. + + Send comments and bug fixes to larrosa@kde.org + or to Antonio Larrosa, Rio Arnoya, 10 5B, 29006 Malaga, Spain + +***************************************************************************/ +#ifndef _channelcfgdlg_h_ +#define _channelcfgdlg_h_ + +#include <kdialogbase.h> + +class QVButtonGroup; +class QRadioButton; +class ChannelViewConfigDialog : public KDialogBase +{ + Q_OBJECT + +public: + + ChannelViewConfigDialog(QWidget *parent,const char *name); + +private: + QVButtonGroup *qbg; + QRadioButton *rb0; + QRadioButton *rb1; + +public slots: + void modeselected(int idx); + +public: + static int selectedmode; +}; + +#endif diff --git a/kmid/channelview.cpp b/kmid/channelview.cpp new file mode 100644 index 00000000..e40857dc --- /dev/null +++ b/kmid/channelview.cpp @@ -0,0 +1,165 @@ +/************************************************************************** + + channelview.cpp - The ChannelView dialog + Copyright (C) 1998 Antonio Larrosa Jimenez + + 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. + + Send comments and bug fixes to larrosa@kde.org + or to Antonio Larrosa, Rio Arnoya, 10 5B, 29006 Malaga, Spain + +***************************************************************************/ + +#include <kapplication.h> +#include <klocale.h> + +#include "channelview.h" +#include "channel3d.h" +#include "channel4d.h" +#include <kconfig.h> + + +ChannelView::ChannelView(void) : KMainWindow(0, "ChannelView") +{ + setCaption(i18n("Channel View")); + for (int i=0;i<16;i++) + { + if (lookMode()==0) + Channel[i]=new KMidChannel3D(i+1,this); + else + Channel[i]=new KMidChannel4D(i+1,this); + connect(Channel[i],SIGNAL(signalToKMidClient(int *)),this,SLOT(slottokmidclient(int *))); + Channel[i]->setGeometry(5,5+i*CHANNELHEIGHT,width()-20,CHANNELHEIGHT); + Channel[i]->show(); + } + scrollbar=new QScrollBar(1,16,1,1,1,QScrollBar::Vertical,this,"Channelscrollbar"); + connect(scrollbar,SIGNAL(valueChanged(int)),this,SLOT(ScrollChn(int))); + setScrollBarRange(); +} + +ChannelView::~ChannelView() +{ + +} + +void ChannelView::closeEvent(QCloseEvent *e) +{ + emit destroyMe(); + e->accept(); +} + +void ChannelView::resizeEvent(QResizeEvent *) +{ + scrollbar->setGeometry(width()-16,0,16,height()); + for (int i=0;i<16;i++) + { + Channel[i]->setGeometry(5,5+(i-(scrollbar->value()-1))*CHANNELHEIGHT,width()-20,CHANNELHEIGHT); + } + setScrollBarRange(); + +} + +void ChannelView::setScrollBarRange(void) +{ + nvisiblechannels=height()/CHANNELHEIGHT; + if (nvisiblechannels<16) + scrollbar->setRange(1,16-nvisiblechannels+1); + else + scrollbar->setRange(1,1); +} + +void ChannelView::ScrollChn(int v) +{ + for (int i=0;i<16;i++) + { + Channel[i]->move(5,5+(i-(v-1))*CHANNELHEIGHT); + } +} + +void ChannelView::noteOn(int chn,int note) +{ + Channel[chn]->noteOn(note); +} + +void ChannelView::noteOff(int chn,int note) +{ + Channel[chn]->noteOff(note); +} + +void ChannelView::changeInstrument(int chn,int pgm) +{ + Channel[chn]->changeInstrument(pgm); +} + +void ChannelView::changeForceState(int chn,bool i) +{ + Channel[chn]->changeForceState(i); +} + + +void ChannelView::reset(int level) +{ + for (int i=0;i<16;i++) + { + Channel[i]->reset(level); + } +} + +int ChannelView::lookmode=0; + +int ChannelView::lookMode(void) +{ + KConfig *kcfg=(KApplication::kApplication())->config(); + + kcfg->setGroup("KMid"); + lookmode=kcfg->readNumEntry("ChannelViewLookMode",0); + + return lookmode; +} + +void ChannelView::lookMode(int i) +{ + KConfig *kcfg=(KApplication::kApplication())->config(); + + lookmode=i; + + kcfg->setGroup("KMid"); + kcfg->writeEntry("ChannelViewLookMode",lookmode); + + bool tmp[128]; + int pgm; + for (int i=0;i<16;i++) + { + Channel[i]->saveState(tmp,&pgm); + delete Channel[i]; + + if (lookmode==0) + Channel[i]=new KMidChannel3D(i+1,this); + else + Channel[i]=new KMidChannel4D(i+1,this); + + connect(Channel[i],SIGNAL(signalToKMidClient(int *)),this,SLOT(slottokmidclient(int *))); + Channel[i]->setGeometry(5,5+(i-(scrollbar->value()-1))*CHANNELHEIGHT,width()-20,CHANNELHEIGHT); + Channel[i]->loadState(tmp,&pgm); + Channel[i]->show(); + } + +} + +void ChannelView::slottokmidclient(int *data) +{ + emit signalToKMidClient(data); +} +#include "channelview.moc" diff --git a/kmid/channelview.h b/kmid/channelview.h new file mode 100644 index 00000000..9534e73a --- /dev/null +++ b/kmid/channelview.h @@ -0,0 +1,76 @@ +/************************************************************************** + + channelview.h - The ChannelView dialog + Copyright (C) 1998 Antonio Larrosa Jimenez + + 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. + + Send comments and bug fixes to larrosa@kde.org + or to Antonio Larrosa, Rio Arnoya, 10 5B, 29006 Malaga, Spain + +***************************************************************************/ + +#ifndef CHANNELVIEW_H +#define CHANNELVIEW_H + +#include <kmainwindow.h> +#include <qscrollbar.h> +#include "channel.h" + + +class ChannelView : public KMainWindow +{ + Q_OBJECT +private: + KMidChannel *Channel[16]; + int nvisiblechannels; + + virtual void resizeEvent(QResizeEvent *); + virtual void closeEvent(QCloseEvent *e); + +public: + ChannelView(void); + virtual ~ChannelView(); + + void setScrollBarRange(void); + + void noteOn(int chn,int note); + void noteOff(int chn,int note); + void changeInstrument(int chn,int pgm); + void changeForceState(int chn,bool i); + + void reset(int level=1); + + static int lookMode(void); + + void lookMode(int i); + +public slots: + void ScrollChn(int i); + void slottokmidclient(int *data); + +signals: + void destroyMe(); + void signalToKMidClient(int *data); + +private: + QScrollBar *scrollbar; + + + static int lookmode; + + +}; +#endif diff --git a/kmid/collectdlg.cpp b/kmid/collectdlg.cpp new file mode 100644 index 00000000..fb79667b --- /dev/null +++ b/kmid/collectdlg.cpp @@ -0,0 +1,307 @@ +/************************************************************************** + + collectdlg.cpp - The collections manager dialog + Copyright (C) 1998 Antonio Larrosa Jimenez + + 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. + + Send comments and bug fixes to larrosa@kde.org + or to Antonio Larrosa, Rio Arnoya, 10 5B, 29006 Malaga, Spain + +***************************************************************************/ +#include <qpushbutton.h> +#include <qlistbox.h> +#include <qlabel.h> + +#include <kapplication.h> +#include <kfiledialog.h> +#include <klocale.h> +#include <kinputdialog.h> +#include <kmessagebox.h> +#include <kurl.h> +#include <kpushbutton.h> +#include <kstdguiitem.h> +#include "collectdlg.h" +#include "version.h" +#include "songlist.h" +#include "slman.h" + +CollectionDialog::CollectionDialog(SLManager *slm,int selC,QWidget *parent,const char *name) : QDialog(parent,name,TRUE) +{ +setCaption(i18n("Collections Manager")); +ok=new KPushButton(KStdGuiItem::ok(),this); +ok->setGeometry(140,200,100,30); +connect(ok,SIGNAL(clicked()),SLOT(accept()) ); +cancel=new KPushButton(KStdGuiItem::cancel(),this); +cancel->setGeometry(250,200,100,30); +connect(cancel,SIGNAL(clicked()),SLOT(reject()) ); + +label=new QLabel(i18n("Available collections:"),this); +label->adjustSize(); +label->move(10,10); +collections=new QListBox(this,"collectionlist"); +collections->setGeometry(10,20+label->height(),340,90); +connect(collections,SIGNAL(highlighted(int)),SLOT(collectionselected(int))); +connect(collections,SIGNAL(selected(int)),SLOT(changeCollectionName(int))); +slman=slm; +for (int i=0;i<=slman->numberOfCollections();i++) + { + collections->insertItem(i18n( slman->getCollectionName(i) ),i); +#ifdef COLLECTDLGDEBUG + printf("Name : %s\n",slman->getCollectionName(i)); +#endif + }; +selectedC=selC; +#ifdef COLLECTDLGDEBUG +printf("selectedC : %d\n",selectedC); +#endif + +label2=new QLabel(i18n("Songs in selected collection:"),this); +label2->adjustSize(); +label2->move(10,collections->y()+collections->height()+10); + +songs=new QListBox(this,"songlist"); +songs->setGeometry(10,label2->y()+label2->height()+10,340,120); +connect(songs,SIGNAL(highlighted(int)),SLOT(songselected(int))); +currentsl=slman->getCollection(selectedC); +if (slman->numberOfCollections()>0) + { + collections->setCurrentItem(selectedC); + collections->centerCurrentItem(); + }; +//fillInSongList(); +newC=new QPushButton(i18n("&New..."),this); +newC->adjustSize(); +newC->move(360,collections->y()+5); +connect(newC,SIGNAL(clicked()),SLOT(newCollection()) ); +copyC=new QPushButton(i18n("&Copy..."),this); +copyC->adjustSize(); +copyC->move(360,newC->y()+newC->height()+5); +connect(copyC,SIGNAL(clicked()),SLOT(copyCollection()) ); +deleteC=new QPushButton(i18n("Delete"),this); +deleteC->adjustSize(); +deleteC->move(360,copyC->y()+copyC->height()+5); +connect(deleteC,SIGNAL(clicked()),SLOT(deleteCollection()) ); + +addS=new QPushButton(i18n("&Add..."),this); +addS->adjustSize(); +addS->move(360,songs->y()+5); +connect(addS,SIGNAL(clicked()),SLOT(addSong()) ); +delS=new QPushButton(i18n("&Remove"),this); +delS->adjustSize(); +delS->move(360,addS->y()+addS->height()+5); +connect(delS,SIGNAL(clicked()),SLOT(removeSong()) ); + +ok->move(ok->x(),songs->y()+songs->height()+10); +cancel->move(ok->x()+ok->width()+5,ok->y()); + +setMinimumSize(400,ok->y()+ok->height()+5); +//setMaximumSize(360,240); +} + +void CollectionDialog::collectionselected(int idx) +{ +selectedC=idx; +#ifdef COLLECTDLGDEBUG +printf("Selected collection: %d\n",selectedC); +#endif +currentsl=slman->getCollection(selectedC); +fillInSongList(); +} + +void CollectionDialog::fillInSongList(void) +{ +QString qs; +songs->clear(); +if (currentsl!=NULL) + { + currentsl->iteratorStart(); + int i=0; + while (!currentsl->iteratorAtEnd()) + { + qs=QString(currentsl->getIteratorName()); + //KURL::decode(qs); + songs->insertItem(qs,i); + currentsl->iteratorNext(); + i++; + }; + songs->setCurrentItem(currentsl->getActiveSongID()-1); + songs->centerCurrentItem(); + }; +} + +void CollectionDialog::songselected(int idx) +{ +selectedS=idx; +currentsl->setActiveSong(idx+1); + +#ifdef COLLECTDLGDEBUG +printf("Selected song: %d\n",selectedS); +#endif +} + +void CollectionDialog::newCollection() +{ + bool ok; + QString name = KInputDialog::getText( i18n( "New Collection" ), + i18n( "Enter the name of the new collection:" ), QString::null, + &ok, this ); + + if (ok) + { + int i=slman->createCollection(name.ascii()); + if (i==-1) + { + QString s = i18n("The name '%1' is already used").arg(name); + KMessageBox::sorry(this, s); + } + else + { + collections->insertItem(name,i); + collections->setCurrentItem(i); + collections->centerCurrentItem(); + }; + }; +} + +void CollectionDialog::copyCollection() +{ +SongList *src=currentsl; +int i; + bool ok; + QString name = KInputDialog::getText( i18n( "Copy Collection" ), + i18n( "Enter the name of the copy collection:" ), QString::null, + &ok, this ); + + if (ok) + { + i=slman->createCollection(name.ascii()); + if (i==-1) + { + QString s = i18n("The name '%1' is already used").arg(name); + KMessageBox::sorry(this, s); + } + else + { + collections->insertItem(name,i); + SongList *tgt=slman->getCollection(i); + src->iteratorStart(); + while (!src->iteratorAtEnd()) + { + tgt->AddSong(src->getIteratorName()); + src->iteratorNext(); + }; + collections->setCurrentItem(i); + collections->centerCurrentItem(); + }; + }; +} + +void CollectionDialog::deleteCollection() +{ +if (selectedC==0) return; +slman->deleteCollection(selectedC); +int i=selectedC; +collections->removeItem(selectedC); +collections->setCurrentItem(i); +collections->centerCurrentItem(); +} + +void CollectionDialog::changeCollectionName(int idx) +{ +if (idx==0) return; + bool ok; + + QString name = KInputDialog::getText( i18n( "Change Collection Name" ), + i18n( "Enter the name of the selected collection:" ), QString::null, + &ok, this ); + + if (ok) + { + if (slman->getCollection(name.ascii())!=NULL) + { + QString s = i18n("The name '%1' is already used").arg(name); + KMessageBox::sorry(this, s); + } + else + { + slman->changeCollectionName(idx,name.ascii()); + collections->changeItem(name,idx); + }; + }; +} + +void CollectionDialog::addSong(const KURL &url) +{ + if (currentsl==NULL) return; + if( url.isEmpty()) return; + + int id=currentsl->AddSong(QFile::encodeName(url.path())); + + if (id==-1) + { + printf("Couldn't add song to collection\n"); + return; + }; + + songs->insertItem(url.fileName(),id-1); +} + + +void CollectionDialog::addSong() +{ + KURL::List urls = KFileDialog::getOpenURLs(":MidiFiles", + "*.kar *.mid *.kar.gz *.mid.gz\n*.kar *.kar.gz\n*.mid *.mid.gz\n*",this); + + KURL::List::Iterator it; + for( it = urls.begin(); it != urls.end(); ++it ) + addSong(*it); + +} + +void CollectionDialog::removeSong() +{ +if (currentsl==NULL) return; +currentsl->DelSong(selectedS+1); +int i=selectedS; +songs->removeItem(selectedS); +songs->setCurrentItem(i); +} + +void CollectionDialog::resizeEvent(QResizeEvent *) +{ +int maxw=newC->width(); +if (copyC->width()>maxw) maxw=copyC->width(); +if (deleteC->width()>maxw) maxw=deleteC->width(); +if (addS->width()>maxw) maxw=addS->width(); +if (delS->width()>maxw) maxw=delS->width(); + +newC->setGeometry(width()-maxw-5,newC->y(),maxw,newC->height()); +copyC->setGeometry(width()-maxw-5,copyC->y(),maxw,copyC->height()); +deleteC->setGeometry(width()-maxw-5,deleteC->y(),maxw,deleteC->height()); + +collections->resize(width()-maxw-20,(height()*35)/100); +label2->move(10,collections->y()+collections->height()+10); +songs->setGeometry(10,label2->y()+label2->height()+10,width()-maxw-20,height()-(label2->y()+label2->height()+10+ok->height()+10)); +addS->setGeometry(width()-maxw-5,songs->y()+5,maxw,addS->height()); +delS->setGeometry(width()-maxw-5,addS->y()+addS->height()+5,maxw,delS->height()); + +cancel->move(width()-cancel->width()-5,height()-cancel->height()-5); +ok->move(cancel->x()-5-ok->width(),height()-ok->height()-5); +} + +int CollectionDialog::selectedC=0; +int CollectionDialog::selectedS=0; +#include "collectdlg.moc" diff --git a/kmid/collectdlg.h b/kmid/collectdlg.h new file mode 100644 index 00000000..46f96ea4 --- /dev/null +++ b/kmid/collectdlg.h @@ -0,0 +1,83 @@ +/************************************************************************** + + collectdlg.h - The collection manager dialog + Copyright (C) 1998 Antonio Larrosa Jimenez + + 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. + + Send comments and bug fixes to larrosa@kde.org + or to Antonio Larrosa, Rio Arnoya, 10 5B, 29006 Malaga, Spain + +***************************************************************************/ +#ifndef _collectdlg_h_ +#define _collectdlg_h_ + +#include <qdialog.h> +#include "songlist.h" +#include "slman.h" + +class QLabel; +class KPushButton; +class QPushButton; +class QListBox; +class KURL; +class CollectionDialog : public QDialog +{ + Q_OBJECT +private: + SLManager *slman; + SongList *currentsl; + +protected: + + virtual void resizeEvent(QResizeEvent *qre); + void fillInSongList(void); //clear the songs list and insert in it + // the songs in currentsl + void addSong(const KURL &); +public: + + CollectionDialog(SLManager *slm,int selc,QWidget *parent,const char *name); + +public slots: + void collectionselected(int idx); + void songselected(int idx); + void newCollection(); + void copyCollection(); + void deleteCollection(); + void changeCollectionName(int idx); + void addSong(); + void removeSong(); + +private: +QLabel *label; +QLabel *label2; +KPushButton *ok; +KPushButton *cancel; +QListBox *collections; +QListBox *songs; +QPushButton *newC; +QPushButton *copyC; +QPushButton *deleteC; +QPushButton *addS; +QPushButton *delS; + + +public: +static int selectedC; +static int selectedS; + +}; + +#endif diff --git a/kmid/configure.in.in b/kmid/configure.in.in new file mode 100644 index 00000000..f1e1d100 --- /dev/null +++ b/kmid/configure.in.in @@ -0,0 +1,5 @@ +KDE_CHECK_HEADER([libkmid/libkmid.h], [kde_mid_compiles=yes], [kde_mid_compiles=no]) +if test $kde_mid_compiles = no; then + DO_NOT_COMPILE="$DO_NOT_COMPILE kmid" +fi + diff --git a/kmid/drums.o3 b/kmid/drums.o3 Binary files differnew file mode 100644 index 00000000..01d9b9c5 --- /dev/null +++ b/kmid/drums.o3 diff --git a/kmid/drums.sb b/kmid/drums.sb Binary files differnew file mode 100644 index 00000000..4bfaf8a3 --- /dev/null +++ b/kmid/drums.sb diff --git a/kmid/examples/DiesIrae.kar b/kmid/examples/DiesIrae.kar Binary files differnew file mode 100644 index 00000000..c54c6fb6 --- /dev/null +++ b/kmid/examples/DiesIrae.kar diff --git a/kmid/examples/Guantanamera.kar b/kmid/examples/Guantanamera.kar Binary files differnew file mode 100644 index 00000000..7fee4b1a --- /dev/null +++ b/kmid/examples/Guantanamera.kar diff --git a/kmid/examples/Makefile.am b/kmid/examples/Makefile.am new file mode 100644 index 00000000..b53f7c54 --- /dev/null +++ b/kmid/examples/Makefile.am @@ -0,0 +1,6 @@ + +example_DATA = OFortuna.kar DiesIrae.kar Guantanamera.kar \ + MariaDeLasMercedes.kar +exampledir = $(kde_datadir)/kmid + +EXTRA_DIST = $(example_DATA) diff --git a/kmid/examples/MariaDeLasMercedes.kar b/kmid/examples/MariaDeLasMercedes.kar Binary files differnew file mode 100644 index 00000000..7a2e305e --- /dev/null +++ b/kmid/examples/MariaDeLasMercedes.kar diff --git a/kmid/examples/OFortuna.kar b/kmid/examples/OFortuna.kar Binary files differnew file mode 100644 index 00000000..cc59960e --- /dev/null +++ b/kmid/examples/OFortuna.kar diff --git a/kmid/hi16-app-kmid.png b/kmid/hi16-app-kmid.png Binary files differnew file mode 100644 index 00000000..dcad9f23 --- /dev/null +++ b/kmid/hi16-app-kmid.png diff --git a/kmid/hi32-app-kmid.png b/kmid/hi32-app-kmid.png Binary files differnew file mode 100644 index 00000000..4538ad78 --- /dev/null +++ b/kmid/hi32-app-kmid.png diff --git a/kmid/hi48-app-kmid.png b/kmid/hi48-app-kmid.png Binary files differnew file mode 100644 index 00000000..928cebca --- /dev/null +++ b/kmid/hi48-app-kmid.png diff --git a/kmid/history.txt b/kmid/history.txt new file mode 100644 index 00000000..c436db0b --- /dev/null +++ b/kmid/history.txt @@ -0,0 +1,567 @@ +Thursday 11-9-97 +- I have started with some tries to make the midi work and due to the + success I have even made an object to manage the midi : midiOut + +Friday 12-9-97 +- Waking up at 7:00am, working from 8:20 to 11:20 and doing some fixes + at 14:20, I have been able to play a midi file through the /dev/sequencer + using the class midiOut and writing some new classes like : midfile + track and some more. + +Saturday 13-9-97 +- Today I have made a midi mapper (object mapper) which read a map config file + and is used to support older synths without general midi compliance. + +Sunday 14-9-97 +- I have made a window, with a KMenuBar, and a KSilder, which reads a mid file + and play it (using a fork) + +Monday 15-9-97 +- fork copy the memory and thus, I cannot tell the player to pause, I have read + much about the subject, and about threads + +Tuesday 16-9-97 +- I have made a small program to test the threads and forks, threads apparently +are faster, but it seems to have a problem with libqt or anyone, and I get +core dumpes what I run kmid even if I only link libpthread but don't use it. +So I've decided to make a fork, in the other way, I've learned to share memory + +Wednesday 17-9-97 +- Christian Esken has told me to use mediatool, but I don't have the +documentation, so I cannot continue work until I get it. + +Thursday 18-9-97 +- Well, I'll continue even without the docs, and when I have them, I will +make the neccesary changes to the code. I have made a few details in windows + +Friday 19-9-97 +- Today I have made the Pause and Stop buttons work. Also, I have made the +slide bar move. And also, I have made a parser of the midi file, which tells +how long the song is, in seconds. If this was little, I have made the interface +between the ui and the player. + +Saturday 20-9-97 +- The interface between the ui and the player doesn't work well, I have to +redesign it because it's difficult to be accurate writing the karaoke at the same that the note plays + +Sunday 21-9-97 +- I have redesigned twice the interface between ui and player and it still +doesn't work well, the first method was creating a list of the karaoke events +and using a timer to process the next event at the right time, but that doesn't +work perfectly, because the text appears a moment after or before the note is +played. The second method is a while loop, which calls processEvents, but +that isn't a very good option, because, though text appears just at the same +time of the note is played, top tells me that kmid is consuming up to 98% of +CPU time, and I don't want to make such a monster. + +Monday 22-9-97 +- Another failed method, and another passed day + +Tuesday 23-9-97 +- Some small changes beautifying the monster to send it to Christian + +Wednesday 24-9-97 +- More debugging and no result. I have uploaded current version to arrakis for +Christian to see it. + +Thursday 25-9-97 +- Eureka ! , at last, I have made the player and the ui run at the same time +with PERFECT syncronisation :-) (at 10:30 pm) + +Friday,Saturday,Sunday 26,27,28-9-97 +- I've been looking at the birds flying freely from tree to tree in all this +weekend, also, I've studied for the test drive. + +Monday 29-9-97 +- I have passed the exam and also, I have (almost) done the karaoke widget +and it works very well ! + +Tuesday 30-9-97 +- The karaoke widget is finished, it also have a scrollbar to see all the +lyrics. By the way, StarTrek : First Contact is a very recommended film + +Wednesday 1-10-97 +- I have fixed pause and stop, which were broken during the karaoke syncro +By the way, kmid consumes 0.0% CPU and 00:00 time while playing a 6 minute song +(and I think that even in longer songs !) + +Thursday 2-10-97 +- I have started classes, so I think I will have less time :-( + +Wednesday 8-10-97 +- The player now recognizes the SETPOS message, but the ui is not syncronized +yet + +Thursday 9-10-97 +- S. R. has "show"ed me the way to initialize the menu, toolbar and client of a +KTopLevelWidget, without the need to resize the window. + +Sunday 12-10-97 +- I have made that all time variables are expressed in milliseconds, so no +more change units !! + +Sunday 19-10-97 +- I have programmed very little this week, but today I have kill a big bug, +now all the songs play well. Some songs were played with some parts faster and +some parts slower than they should (thanks to Christian Esken for reporting + the bug!) + +Tuesday 21-10-97 +- WOE, KDE-Beta-ONE is even better than before. But now kmid doesn't compile (?) + +Wednesday 22-10-97 +- After compiling the kde libs, kmid compiles ok. KSlider has changed and its +behaviour (Arrrgh!), so I have trickered a little the code. + +Thursday 23-10-97 +- I have cleaned a little the code. + +Friday 24-10-97 +- I started to "rewrite" the track class to make the slider work well + +Saturday 25-10-97 +- I have passed the day working in the time. + +Sunday 26-10-97 +- Eureka !!!, KMid works great! with good timings and syncronization between + O ~ music and lyrics. + U + \_/ + +Monday 27-10-97 +- After 10 hours in the university, I have made the final touches to send +kmid 0.1 to the internet. + +??? 7-11-97 +- Finally, there's an impossible-better syncro between the program +and the user !!!. I mean, that when you press the pause button, the music +is inmediatly paused !!! + +Saturday 8-11-97 +- So I suppose yesterday was Friday, but I should demostrate it :-) +I have added drag & drop support in kmid to load files by dropping them from kfm +Also made the slider show the time played at resizeable steps + +Sunday 9-11-97 +- Today I have made possible to change the font and I have made an icon. +Prepare a version to upload tomorrow to the internet. + +Thursday 13-11-97 +- I have nearly rewritten (made lots of changes to) the lyrics display widget +Also fixed that old "bug" that let in black the last word of a phrase in some +songs. + +Friday 14-11-97 +- Automatic text event chooser is done ! +- Fixed a bug that could freeze kmid under very rare circunstances. +- Added more support for incomplete/broken files + +Saturday 15-11-97 +- I have changed the exit-behaviour for a messagebox-behaviour +- Fixed a bug that could leave the children running when closing kmid + +Sunday 16-11-97 +- KMid adds a mime entry for karaoke files in audio/x-karaoke +- Real Session Management. +- Made the first rpm of kmid. + +Monday 17-11-97 +- Release version 0.3 in tgz and rpm + +Friday 28-11-97 +- I've been quite busy this week, but I have had reports and patches :-) on +how to make kmid to work with an AWE, a GUS, and in FreeBSD :-)))) + +Monday 8-12-97 +- I have fixed a small bug with which the time that a song longs was not well +reported. +- Also a tiny bug in consolekmid + +Tuesday 9-12-97 +- I've made the first feature that I've been asked for. Another thing to map +with the midi mapper for Dietmar's PSR500 + +Friday 12-12-97 +- Nearly done the map chooser so that there will no be needed to edit the kmidrc +for anything. +Now when you choose a new map or change GM/MT32 mode, the music is automatically +changed while playing !. + +...... **-12-97 +- I have been the rest of the month implementing a midi server that I will +call KMidServer and that will provide any application with easy control over +midi functions. + +30-12-97 +- KMid now can play gzipped midi files just as any other normal file. + +.... **-1-98 +- I have improved the midi mapper by allowing to factor the pitch bender. + Now pitch benders works OK !! (at last I have improved the windows mapper :-) + I have also added support to convert expression events to volume events. +* I have been doing the kfourier this month and studying (little time to do more) + + +Thursday 5-2-98 +- After doing my first exam this year, I have decided to calm things a little + by programming something. I have made the options added to the mapper available +through the config map file. + +Monday 9-2-98 +- 2nd exam done and a bug that I introduced last thrusday fixed. + +Friday 20-2-98 +- I've finished exams, have installed the yesterday snapshots and have +updated the configure scripts to add rpath and all that stuff to my copy +of kmid (thanks to Kulow, who added it to kmid in kdemultimedia) + +Saturday 21-2-98 +- Fixed the not-a-feature problem with FM, next time I will not let the +option for the user to select something that doesn't work. +Final touches to release kmid 0.41 tomorrow morning. + +Monday 23-2-98 +- I've started working on FM support (and it goes very fast) + +Tuesday 24-2-98 +- fm already works, but notes are shifted to a higher key !!! +Also pitch bender seems not to be accurate. + +Wednesday 25-2-98 +- pitch bender is now fixed, and also the shift of notes, now the problem + is that some notes are lost (always from the same track/channel/patch?!?!) + +Friday 27-2-98 +- The problem with the lost notes is fixed :-/, the problem was that some +notes are played through the left speaker and some thru the right speaker, +and my wires for the right speaker were broken, but it wasn't noted with +the surround activated :-))))))) (Sometimes I feel real shame). Three days +lost in that !! + +Saturday 28-2-98 +- I've gone to the country and I've done the internals of the playlists in a +486/50 without linux, so I'll compile the Monday. + +Sunday 1-3-98 +- Some test with multiple toolbars. + +Monday 2-3-98 +- Started to do the collections manager dialog + +Tuesday 3-3-98 +- The collections manager dialog is done. + +Wednesday 4-3-98 +- KKeyConfig is a really good class, easy to use to make the karaoke scroll +when arrow keys are pressed. + +Thursday 5-3-98 +- I've done the playlist hardest part, now it works and there's only left + some final touches to do + +Tuesday 10-3-98 +- Playlists are finally working ok. + +Wednesday 11-3-98 +- Fixed the session management (in fact, I've changed it a little to support +collections) + +Thursday 12-3-98 +- Fixed some small bugs. + +Friday 13-3-98 +- I have replaced my new Makefiles.am (just two days old) with the one +of Stephan Kulow which look much better. + +Saturday 14-3-98 +- Finished deleting printf's to upload kmid tomorrow :-) + +Sunday 15-3-98 +- Upload it, but as I forgot to delete some printf messages :-( , I had +to quickly do a fix and send also 0.5.1 + +**** **-3-98 +- I've passed many days configuring the modem, the internet connection, +sendmail, kppp, cvs and all those programs :-) + +Monday 30-3-98 +- I've implemented the save-Lyrics feature that Adrian Knoth suggested (thanks!) + +Tuesday 31-3-98 +- I've done some changes to support the new KFileDialog and the new +changes in kdelibs done by Matthias. + +Thursday 2-4-98 +- Some bug fixes + +Monday 6-4-98 +- I've found and fixed a memory leakage bug, I forgot to delete the +SpecialEvents from each song, so kmid was using more and more memory with +each opened song. + +Tuesday 7-4-98 +- Aaaargh !, I have to remove the changes that I did last tuesday because it +seems that the changes in the kdelibs have been removed. + +Monday 13-4-98 +- Added support for midi files with strange headers not related to midi files. + (suggested by Adrian Knoth, thanks !) + +Friday 24-4-98 +- At last, I have had some free time and have done some things: + 1. Finally fixed the synchronization between gui and player (hopefully forever) + 2. Fixed a problem openning a gzipped file with spaces in its name + 3. Fixed a bug which caused kmid to freeze if collection has only 1 song, and + trying to play next song in aleatory mode. + 4. Fixed the problem which made some songs to play at a lower volume when + moving the slider, but no if playing from the beginning + That's all for now :-) , there have been so many changes that I've call + this version 0.5.3 + +Thursday 7-5-98 +- Released version 0.6 to update my homepage which was getting very outdated + +Saturday 9-5-98 +- After fixing my midi cable, I've noticed that fm is (as Gyula Kerekes + reported), playing in mono, and I've fixed it. + +Sunday 10-5-98 +- I've fixed a small bug with which midi files without text events (nor lyrics) +got the time slider very desynchronized after pausing for a long time. + +Monday 25-5-98 +- Applied a patch submitted by Kevin Street, to compile kmid on FreeBSD 3.0 +systems with awe support (directory settings has changed since 2.2) + +Saturday 20-6-98 +- I'm on exams, but just to relax a few minutes I've been hunting for bugs :-) + +Sunday 21-6-98 +- Wow, KDE-1.0 is finally here, and it is REAL, so I will prepare very quickly +KMid 1.0 before the freeze of kdemultimedia. + +Saturday 4-7-98 +- Just finished exams :-), and I've implemented the (long awaited feature of a) +volume bar. + +Sunday 5-7-98 +- I'm doing a channel view in which you can see the keys being pressed +and released, it's very nice :-) + +Monday 6-7-98 +- Using the (still hot) shutDown signal (the most awaited thing for +kmid) + +Monday 13-7-98 +- I've restructured the Channel view, it's much nicer and allows for easier +expansion. It also shows the used instrument + +Saturday 15-8-98 +- Wow, I haven't updated this file for so long ... + I've finished the changing instrument feature and so the channel view. + I've also improved speed a little by supressing some parses to the midi file. + I have improved consolekmid, now it is much more usuable. + Finally, I've changed the sources to use the KAccel class. + +Monday 31-8-98 +- I've fixed some bugs, the most important one being that kmid left its player + processes as zombies after stopping playing (it worked ok, but now it doesn't, + dunno why). That problem made to appear some weird dialogs telling "song is already + playing" at each moment +- I left a color hardcoded in button*.xpm when it should be Transparent (not + everybody has a window background color of #5D5D8F8FA0A0 :-) ) +- I created a Motif 1.0 combo box in the channelview, but it should be Motif 2.0 + because 1.0 has a "feature" for large como boxes (as this one) + + +Wednesday 9-9-98 +- Fixed the last bug for leaving zombies around. + +Monday 14-9-98 +- Released Version 1.2 + +Tuesday 15-9-98 +- Added the change tempo widget and the KTriangleButton widget + +Wednesday 16-9-98 +- It's possible now to change the tempo of a song. + +Thursday 1-10-98 +- Fixed some problems + +Thursday 15-10-98 +- FIXED !!! + The long awaited fix has arrived for songs keeping playing after X11' logout + when channelview was actived. + Now also the ChannelView change its colors when the user change the + global colors, kdisptext paints a frame over the karaoke text, + KLCDNumber only accepts a range of values (from 3 to 999) + +Friday 16-10-98 +- Improved support for really broken files. +- Added some translations to Spanish + +Friday 23-10-98 +- I've started writing the internals of a rhythm view + +Saturday 24-10-98 +- Now KMid shows a new widget to make easier follow the rhythm of songs. + I've also fixed a small bug by which the tempo (and rhythm) changed its + state before the event actually happening if you moved the timebar near + before the event time. The problem was caused by volatile shared variables. + +Sunday 25-10-98 +- Fixed a serious bug I introduced in the previous commitment + +Monday 2-11-98 +- Fixed some problems + +Sunday 8-11-98 +- Some small changes + +Wednesday 25-11-98 +- I've finally fixed the bug that made kmid play music sometimes +faster and sometimes slower on some machines (i.e. mine, since I installed +kernel 2.0.36) +This bug was there since the real beginning, and now, it is FIXED. +This deserves a new 2.0 version, probably next week. + +Friday 27-11-98 +- Fixed a broken link in the .kdelnk file (DocPath) and raised version +number to 1.6 + +Thursday 10-12-98 +- Added new sgml documentation, updated up to KMid 1.6 + +Friday 11-12-98 +- Fixed a shared memory leackage bug (hopefully the last bug in KMid :) ). + +Thursday 17-12-98 +- Initial support for SoftOSS (this is making some sound now :)) +- Indentified the player directory sources and beautified them a little + +Friday 18-12-98 +- Fixed a geometry layout bug + +Sunday 20-12-98 +- Fixed a problem when [un]installing midi devices (not such a mad idea if you +use kernel modules) that made kmid segfault because it couldn't found +the device. + +Saturday 16-1-99 +- Decode URL before showing it on the screen. + +Thursday 21-1-99 +- Fixed a null pointer access while generating beats, because I didn't +checked for songs which didn't contain any spev (songs which use absolute 0 spev +are extremely rare to find, as any song must include at least a tempo event) + +Tuesday 26-1-99 +- Removed ; after QOBJECT and fixed default midi map in consolekmid (not kmid) + +Sunday 21-2-99 +- Made a quick hack (no more than 15 lines) and kmid uses KIOJob to be +net transparent (now it can download files using an http or ftp protocol just +using dnd from a kfm window or using the open file dialog) + +Saturday 6-3-99 +- The sound driver in Linux kernels from the 2.2.x series work very different +than the ones in 2.0.x so kmid was severely damaged. After several days of +hacking (and after getting from A.Cox that this wasn't going to be fixed in the +kernel) I've found a fix that even works in the 2.0.x kernels. + +Sunday 21-3-99 +- Fixed the high pitch of AWE cards (thanks to Joseph H. Buehler and Takashi Iwai for + the indications) +- Raised version number to 1.7 + +Friday 2-4-99 +- Did a workaround for a bug in egcs which doesn't seem to optimize simple +return-a-value function as an inline function when using -O2 and it made kmid +freeze under certain conditions when parsing some midi files. + +- Removed a comparison of double variables which is very dangerous (_even_ after +storing in one of them the value of the other one) +- Fixed a problem by which kmid didn't play the last half second or so of some songs. + +Thursday 8-4-99 +- Fixed a problem that made Kmid consume 99% of CPU since a month ago. Now it's back +to the usual 0.00% of CPU use :-) + +Monday 12-4-99 +- Fixed a bug that made KMid freeze when trying to open a directory + +Thursday 15-4-99 +- Better support for broken karaoke files which has duplicated lyrics + +Thursday 11-11-99 +- Fixed a problem with corrupt files that suddenly doesn't work (but KMid + from the 1.1 branch works ok (?) ). Anyway, I've got it to work even + better with broken files +- Fixed the KLed usage, which was broken since the KLedLamp -> KLed transition. +- Fixed a repaint bug with the time tags that has been here for too long. + +Friday 12-11-99 +- Instead of using manual layout, let's use QLayouts (there are still some + problems with this ) +- Added xdnd support (finally !) + +Thursday 25-11-99 +- Changed a lot of code to look much better +- Fixed many problems when painting lyrics in different colors + +Friday 26-11-99 +- The lyrics display doesn't flicker anymore (finally :-) ) +- Reworked the scrolling code, it's smooth now instead of line-by-line (but also + makes consumes a bit of CPU, so I'll make it configurable for people who don't + want to waste resources) +- note: don't call resizeContents from drawContents, or you'll have some + problems (QScrollView bug ?, anyway, this note should be on the docs) + +Tuesday 11-1-2000 +- SoftOSS is working now ! +- Added LOTS of documentation to the MIDI library. Anyway, there's a lot more +to come. +- Also fixed a few problems in the lyrics display, and added a new option +to consolekmid + +Sunday 27-2-2000 +- Ported KMid to use the "official" LibKMid and KXMLGUI, with the following + result : + # wc kmidframe.cpp + Before: 769 1450 24820 kmidframe.cpp + After : 622 1171 19045 kmidframe.cpp + +Monday 28-2-2000 +- Added ALSA support to libkmid + +Tuesday 29-2-2000 +- I'm making KMid a part + +It took me : exactly 13 minutes to port the app + 30 seconds to do /LD/LIB/ in Makefile.am + 5:14 to compile it and see that kbrowser.h doesn't exist now :( + +Sunday 5-3-2000 +- Now libkmid does build and run on systems where OSS is not installed. +- Updated the code to simplify it a bit due to libkmid changes. +- I still have to search for a bug that makes KMid (and the part!) to crash + when destroying KDisplayText (the curious thing is that it crashes on + QScrollView) + +Sunday 2-4-2000 +- Now Libkmid links with kdecore and qt in order to use a KConfig object to +read the default settings as saved by the user with the midi kcontrol module. +- It creates a "dummy" KInstance in case of the application being a non-KDE +application. +- Fixed compilation of KMid, as 1) someone renamed klinedit.h to klineedit.h +and 2) now we have to include qiconset.h when creating an action with pictures +as in kmid_part.cpp +- Now I just have to find why KMid doesn't show any interface except the +standard actions + +Saturday 30-9-2000 +- Hmm, it's been a long time since I don't update this file. In summer + I've fixed ALSA support and many related bugs. +- Today, I've finally added the accelerators. +- Raised version to 2.0 diff --git a/kmid/instrfilter.awk b/kmid/instrfilter.awk new file mode 100644 index 00000000..078169aa --- /dev/null +++ b/kmid/instrfilter.awk @@ -0,0 +1,2 @@ +{ match ($0,"\".*\"") } +{ if (RSTART>0) print "i18n("substr($0,RSTART,RLENGTH)");" }; diff --git a/kmid/instrname.cpp b/kmid/instrname.cpp new file mode 100644 index 00000000..551b85c9 --- /dev/null +++ b/kmid/instrname.cpp @@ -0,0 +1,132 @@ +const char *instrumentName[128]={ + "Acoustic Grand Piano", + "Bright Acoustic Piano", + "Electric Grand Piano", + "Honky-Tonk", + "Rhodes Piano", + "Chorused Piano", + "Harpsichord", + "Clavinet", + "Celesta", + "Glockenspiel", + "Music Box", + "Vibraphone", + "Marimba", + "Xylophone", + "Tubular Bells", + "Dulcimer", + "Hammond Organ", + "Percussive Organ", + "Rock Organ", + "Church Organ", + "Reed Organ", + "Accordion", + "Harmonica", + "Tango Accordion", + "Acoustic Guitar (Nylon)", + "Acoustic Guitar (Steel)", + "Electric Guitar (Jazz)", + "Electric Guitar (Clean)", + "Electric Guitar (Muted)", + "Overdriven Guitar", + "Distortion Guitar", + "Guitar Harmonics", + "Acoustic Bass", + "Electric Bass (Finger)", + "Electric Bass (Pick)", + "Fretless Bass", + "Slap Bass 1", + "Slap Bass 2", + "Synth Bass 1", + "Synth Bass 2", + "Violin", + "Viola", + "Cello", + "Contrabass", + "Tremolo Strings", + "Pizzicato Strings", + "Orchestral Harp", + "Timpani", + "String Ensemble 1", + "String Ensemble 2", + "Synth Strings 1", + "Synth Strings 2", + "Choir Aahs", + "Voice Oohs", + "Synth Voice", + "Orchestra Hit", + "Trumpet", + "Trombone", + "Tuba", + "Muted Trumpet", + "French Horn", + "Brass Section", + "Synth Brass 1", + "Synth Brass 2", + "Soprano Sax", + "Alto Sax", + "Tenor Sax", + "Baritone Sax", + "Oboe", + "English Horn", + "Bassoon", + "Clarinet", + "Piccolo", + "Flute", + "Recorder", + "Pan Flute", + "Blown Bottle", + "Shakuhachi", + "Whistle", + "Ocarina", + "Lead 1 - Square Wave", + "Lead 2 - Saw Tooth", + "Lead 3 - Calliope", + "Lead 4 - Chiflead", + "Lead 5 - Charang", + "Lead 6 - Voice", + "Lead 7 - Fifths", + "Lead 8 - Bass+Lead", + "Pad 1 - New Age", + "Pad 2 - Warm", + "Pad 3 - Polysynth", + "Pad 4 - Choir", + "Pad 5 - Bow", + "Pad 6 - Metallic", + "Pad 7 - Halo", + "Pad 8 - Sweep", + "FX 1 - Rain", + "FX 2 - Soundtrack", + "FX 3 - Crystal", + "FX 4 - Atmosphere", + "FX 5 - Brightness", + "FX 6 - Goblins", + "FX 7 - Echoes", + "FX 8 - Sci-fi", + "Sitar", + "Banjo", + "Shamisen", + "Koto", + "Kalimba", + "Bagpipe", + "Fiddle", + "Shannai", + "Tinkle Bell", + "Agogo", + "Steel Drum", + "Wook Block", + "Taiko Drum", + "Melodic Tom", + "Synth Drum", + "Reverse Cymbal", + "Guitar Fret Noise", + "Breath Noise", + "Seashore", + "Bird Tweet", + "Telephone", + "Helicopter", + "Applause", + "Gunshot" +}; + + diff --git a/kmid/instrname.h b/kmid/instrname.h new file mode 100644 index 00000000..80e199c4 --- /dev/null +++ b/kmid/instrname.h @@ -0,0 +1,6 @@ +#ifndef _INSTRNAME_H +#define _INSTRNAME_H + +extern const char *instrumentName[128]; + +#endif diff --git a/kmid/instrname.i18n b/kmid/instrname.i18n new file mode 100644 index 00000000..08ec0938 --- /dev/null +++ b/kmid/instrname.i18n @@ -0,0 +1,133 @@ +/* This is an automatically generated file + * DO NOT EDIT !!! + * To create this file run : make instrname.i18n + */ + +i18n("Acoustic Grand Piano"); +i18n("Bright Acoustic Piano"); +i18n("Electric Grand Piano"); +i18n("Honky-Tonk"); +i18n("Rhodes Piano"); +i18n("Chorused Piano"); +i18n("Harpsichord"); +i18n("Clavinet"); +i18n("Celesta"); +i18n("Glockenspiel"); +i18n("Music Box"); +i18n("Vibraphone"); +i18n("Marimba"); +i18n("Xylophone"); +i18n("Tubular Bells"); +i18n("Dulcimer"); +i18n("Hammond Organ"); +i18n("Percussive Organ"); +i18n("Rock Organ"); +i18n("Church Organ"); +i18n("Reed Organ"); +i18n("Accordion"); +i18n("Harmonica"); +i18n("Tango Accordion"); +i18n("Acoustic Guitar (Nylon)"); +i18n("Acoustic Guitar (Steel)"); +i18n("Electric Guitar (Jazz)"); +i18n("Electric Guitar (Clean)"); +i18n("Electric Guitar (Muted)"); +i18n("Overdriven Guitar"); +i18n("Distortion Guitar"); +i18n("Guitar Harmonics"); +i18n("Acoustic Bass"); +i18n("Electric Bass (Finger)"); +i18n("Electric Bass (Pick)"); +i18n("Fretless Bass"); +i18n("Slap Bass 1"); +i18n("Slap Bass 2"); +i18n("Synth Bass 1"); +i18n("Synth Bass 2"); +i18n("Violin"); +i18n("Viola"); +i18n("Cello"); +i18n("Contrabass"); +i18n("Tremolo Strings"); +i18n("Pizzicato Strings"); +i18n("Orchestral Harp"); +i18n("Timpani"); +i18n("String Ensemble 1"); +i18n("String Ensemble 2"); +i18n("Synth Strings 1"); +i18n("Synth Strings 2"); +i18n("Choir Aahs"); +i18n("Voice Oohs"); +i18n("Synth Voice"); +i18n("Orchestra Hit"); +i18n("Trumpet"); +i18n("Trombone"); +i18n("Tuba"); +i18n("Muted Trumpet"); +i18n("French Horn"); +i18n("Brass Section"); +i18n("Synth Brass 1"); +i18n("Synth Brass 2"); +i18n("Soprano Sax"); +i18n("Alto Sax"); +i18n("Tenor Sax"); +i18n("Baritone Sax"); +i18n("Oboe"); +i18n("English Horn"); +i18n("Bassoon"); +i18n("Clarinet"); +i18n("Piccolo"); +i18n("Flute"); +i18n("Recorder"); +i18n("Pan Flute"); +i18n("Blown Bottle"); +i18n("Shakuhachi"); +i18n("Whistle"); +i18n("Ocarina"); +i18n("Lead 1 - Square Wave"); +i18n("Lead 2 - Saw Tooth"); +i18n("Lead 3 - Calliope"); +i18n("Lead 4 - Chiflead"); +i18n("Lead 5 - Charang"); +i18n("Lead 6 - Voice"); +i18n("Lead 7 - Fifths"); +i18n("Lead 8 - Bass+Lead"); +i18n("Pad 1 - New Age"); +i18n("Pad 2 - Warm"); +i18n("Pad 3 - Polysynth"); +i18n("Pad 4 - Choir"); +i18n("Pad 5 - Bow"); +i18n("Pad 6 - Metallic"); +i18n("Pad 7 - Halo"); +i18n("Pad 8 - Sweep"); +i18n("FX 1 - Rain"); +i18n("FX 2 - Soundtrack"); +i18n("FX 3 - Crystal"); +i18n("FX 4 - Atmosphere"); +i18n("FX 5 - Brightness"); +i18n("FX 6 - Goblins"); +i18n("FX 7 - Echoes"); +i18n("FX 8 - Sci-fi"); +i18n("Sitar"); +i18n("Banjo"); +i18n("Shamisen"); +i18n("Koto"); +i18n("Kalimba"); +i18n("Bagpipe"); +i18n("Fiddle"); +i18n("Shannai"); +i18n("Tinkle Bell"); +i18n("Agogo"); +i18n("Steel Drum"); +i18n("Wook Block"); +i18n("Taiko Drum"); +i18n("Melodic Tom"); +i18n("Synth Drum"); +i18n("Reverse Cymbal"); +i18n("Guitar Fret Noise"); +i18n("Breath Noise"); +i18n("Seashore"); +i18n("Bird Tweet"); +i18n("Telephone"); +i18n("Helicopter"); +i18n("Applause"); +i18n("Gunshot"); diff --git a/kmid/kdisptext.cpp b/kmid/kdisptext.cpp new file mode 100644 index 00000000..c871e55a --- /dev/null +++ b/kmid/kdisptext.cpp @@ -0,0 +1,640 @@ +/************************************************************************** + + kdisptext.cpp - The widget that displays the karaoke/lyrics text + Copyright (C) 1997,98 Antonio Larrosa Jimenez + + 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. + + Send comments and bug fixes to larrosa@kde.org + or to Antonio Larrosa, Rio Arnoya, 10 5B, 29006 Malaga, Spain + +***************************************************************************/ +#include "kdisptext.h" +#include <qpainter.h> +#include <qfont.h> +#include <qfontmetrics.h> +#include <qrect.h> +#include <qtextcodec.h> + +#include <kconfig.h> +#include <kglobal.h> +#include <kglobalsettings.h> +#include <kinstance.h> +#include <klocale.h> +#include "version.h" + + +#define NUMPREVLINES 2 +//#define DRAW_BOUNDING_RECTS + + +KDisplayText::KDisplayText(QWidget *parent,const char *name) : QScrollView(parent,name) +{ + first_line_[0]=first_line_[1]=NULL; + linked_list_[0]=linked_list_[1]=NULL; + cursor_line_[0]=cursor_line_[1]=NULL; + cursor_[0]=cursor_[1]=NULL; + nlines_[0]=nlines_[1]=0; + linked_list=NULL; + cursor_line=NULL; + first_line=NULL; + cursor=NULL; + nlines=0; + lyrics_codec=KGlobal::locale()->codecForEncoding(); + + viewport()->setBackgroundColor(QColor (110,110,110)); +// setBackgroundMode(NoBackground); + KConfig *kcfg=KGlobal::instance()->config(); + kcfg->setGroup("KMid"); + typeoftextevents=kcfg->readNumEntry("TypeOfTextEvents",1); + QFont *qtextfontdefault=new QFont(KGlobalSettings::fixedFont().family(),22); + qtextfont=new QFont(kcfg->readFontEntry("KaraokeFont",qtextfontdefault)); + delete qtextfontdefault; + qfmetr=new QFontMetrics(*qtextfont); + nvisiblelines=height()/qfmetr->lineSpacing(); + autoscrollv=0; +} + +KDisplayText::~KDisplayText() +{ + RemoveLinkedList(); +} + +/*void KDisplayText::PreDestroyer(void) +{ + delete qfmetr; + delete qtextfont; +} +*/ + +void KDisplayText::RemoveLine(kdispt_line *tmpl) +{ + kdispt_ev *tmpe; + while (tmpl->ev!=NULL) + { + tmpe=tmpl->ev; + tmpl->ev=tmpe->next; + // delete tmpe->spev; Remember that the Special Events that this pointer + // points to is the same that the Player object has instantiated + delete tmpe; + } +} + +void KDisplayText::RemoveLinkedList(void) +{ + cursor=NULL; + cursor_line=NULL; + first_line=NULL; + linked_list=NULL; + nlines=0; + nlines_[0]=nlines_[1]=0; + first_line_[0]=first_line_[1]=NULL; + cursor_line_[0]=cursor_line_[1]=NULL; + cursor_[0]=cursor_[1]=NULL; + + kdispt_line *tmpl; + for (int i=0;i<2;i++) + { + while (linked_list_[i]!=NULL) + { + RemoveLine(linked_list_[i]); + tmpl=linked_list_[i]; + linked_list_[i]=linked_list_[i]->next; + delete tmpl; + } + } +} + +void KDisplayText::ClearEv(bool totally) +{ + RemoveLinkedList(); + if (totally) + { + killTimers(); + autoscrollv=0; + resizeContents(0,0); + viewport()->repaint(TRUE); + } +} + +int KDisplayText::IsLineFeed(char c,int type) +{ + switch (type) + { + case (1) : if (/*(c==0)||*/(c=='\\')||(c=='/')||(c=='@')) return 1;break; + case (5) : if (/*(c==0)||*/(c==10)||(c==13)) return 1;break; + default : if ((c==0)||(c==10)||(c==13)||(c=='\\')||(c=='/')||(c=='@')) return 1;break; + } + return 0; +} + +void KDisplayText::AddEv(SpecialEvent *ev) +{ + if ((ev->type==1) || (ev->type==5)) + { + int idx=(ev->type==1)? 0 : 1; + if (linked_list_[idx]==NULL) + { + linked_list_[idx]=new kdispt_line; + linked_list_[idx]->next=NULL; + linked_list_[idx]->num=1; + linked_list_[idx]->ev=new kdispt_ev; + cursor_line_[idx]=linked_list_[idx]; + cursor_[idx]=cursor_line_[idx]->ev; + cursor_[idx]->spev=ev; + cursor_[idx]->next=NULL; + first_line_[idx]=linked_list_[idx]; + first_line=first_line_[idx]; + nlines_[idx]=1; + } + else + { + if (IsLineFeed(ev->text[0],ev->type)) + { + nlines_[idx]++; + cursor_line_[idx]->next=new kdispt_line; + cursor_line_[idx]=cursor_line_[idx]->next; + cursor_line_[idx]->num=nlines_[idx]; + cursor_line_[idx]->ev=new kdispt_ev; + cursor_line_[idx]->next=NULL; + cursor_[idx]=cursor_line_[idx]->ev; + } + else + { + cursor_[idx]->next=new kdispt_ev; + cursor_[idx]=cursor_[idx]->next; + } + cursor_[idx]->spev=ev; + cursor_[idx]->next=NULL; + } + } +} + +void KDisplayText::calculatePositions(void) +{ + int typeoftextevents=1; + int fin=0; + kdispt_line *tmpl; + kdispt_ev *tmp; + int tmpx=0; + int tmpy=0; + int tmpw=0; + int maxx=0; + nlines=nlines_[(typeoftextevents==1)? 0:1]; + int lineSpacing=qfmetr->lineSpacing(); + int descent=qfmetr->descent(); + while (!fin) + { + tmpl=linked_list_[(typeoftextevents==1)?0:1]; + tmpy=lineSpacing; + maxx=0; + while (tmpl!=NULL) + { + tmp=tmpl->ev; + tmpx=5; + while (tmp!=NULL) + { + if (tmp->spev->type==typeoftextevents) + { + if (IsLineFeed(tmp->spev->text[0],typeoftextevents)) + { + tmpy+=lineSpacing; + tmpx=5; + + tmp->xpos=tmpx; + if (tmp->spev->text[0]!=0) tmpw=qfmetr->width(lyrics_codec->toUnicode(&tmp->spev->text[1])); + else tmpw=0; + tmp->r=qfmetr->boundingRect(lyrics_codec->toUnicode(&tmp->spev->text[1])); + } + else + { + tmp->xpos=tmpx; + tmpw=qfmetr->width(lyrics_codec->toUnicode(tmp->spev->text)); + tmp->r=qfmetr->boundingRect(lyrics_codec->toUnicode(tmp->spev->text)); + } + // We add 5 pixels above, below and to the right because of a + // problem with latest released Xft + tmp->r.moveBy(tmpx,tmpy-tmp->r.height()-tmp->r.y()-5); + tmp->r.setHeight(tmp->r.height()+descent+10); + tmp->r.setWidth(tmp->r.width()+5); + tmpx+=tmpw; + if (tmpx>maxx) maxx=tmpx; + } + tmp=tmp->next; + } + tmpl->ypos=tmpl->num*lineSpacing; + tmpy=tmpl->ypos; + tmpl=tmpl->next; + } + maxX[(typeoftextevents==1)?0:1]=maxx+10; + maxY[(typeoftextevents==1)?0:1]= + nlines_[(typeoftextevents==1)?0:1]*lineSpacing+descent+10; + + if (typeoftextevents==1) typeoftextevents=5; + else fin=1; + } + +} + +kdispt_line *KDisplayText::searchYOffset(int y, kdispt_line *start) +{ +kdispt_line *t=start; +while (t!=NULL) + { +// if (t->ypos+qfmetr->descent()>y) return start; + if (t->ypos+qfmetr->descent()+20>y) return start; + start=t; + t=t->next; + }; +return start; +} + +void KDisplayText::drawContents(QPainter *p, int /*clipx*/, int clipy, int /*clipw*/, int cliph) +{ + p->setFont(*qtextfont); + if (linked_list==NULL) return; + int i=0; + p->setPen(yellow); + int colorplayed=1; + if (cursor==NULL) colorplayed=0; // Thus, the program doesn't change the color + kdispt_line *tmpl=linked_list; + kdispt_ev *tmp; + +#ifdef KDISPTEXTDEBUG + printf("events displayed %d\n",typeoftextevents); +#endif + + tmpl=searchYOffset(clipy,linked_list); + int nlinestodraw=1; + kdispt_line *t=tmpl; + while ((t!=NULL)&&(t->ypos+qfmetr->descent()<clipy+cliph)) + { + nlinestodraw++; + t=t->next; + } + + i=0; + while ((i<nlinestodraw)&&(tmpl!=NULL)) + { + tmp=tmpl->ev; + while ((tmp!=NULL)&&(tmp->spev->type!=typeoftextevents)) tmp=tmp->next; + while (tmp!=NULL) + { + if ( colorplayed && + // (tmp->spev->absmilliseconds>=cursor->spev->absmilliseconds)) + (tmp->spev->id>=cursor->spev->id)) + { + p->setPen(black); + colorplayed=0; + } + + if (IsLineFeed(tmp->spev->text[0],tmp->spev->type)) + p->drawText(tmp->xpos,tmpl->ypos,lyrics_codec->toUnicode(&tmp->spev->text[1])); + else + p->drawText(tmp->xpos,tmpl->ypos,lyrics_codec->toUnicode(tmp->spev->text)); + +#ifdef DRAW_BOUNDING_RECTS + p->setPen(red); + p->drawRect(tmp->r); + p->setPen((colorplayed)?yellow:black); +#endif + tmp=tmp->next; + while ((tmp!=NULL)&&(tmp->spev->type!=typeoftextevents)) tmp=tmp->next; + } + i++; + tmpl=tmpl->next; + } + +} + + +void KDisplayText::resizeEvent(QResizeEvent *e) +{ + QScrollView::resizeEvent(e); + nvisiblelines=visibleHeight()/qfmetr->lineSpacing(); + if ( (nlines>nvisiblelines) || (nvisiblelines==0) ) + resizeContents(maxX[(typeoftextevents==1)?0:1],maxY[(typeoftextevents==1)?0:1]); + else + resizeContents(0,0); + +} + +void KDisplayText::CursorToHome(void) +{ +/* KConfig *kcfg=KGlobal::instance()->config(); + kcfg->setGroup("KMid"); + typeoftextevents=kcfg->readNumEntry("TypeOfTextEvents",1); +*/ + linked_list=linked_list_[(typeoftextevents==1)? 0:1]; + nlines=nlines_[(typeoftextevents==1)? 0:1]; + cursor_line_[0]=linked_list_[0]; + first_line_[0]=cursor_line_[0]; + if (cursor_line_[0]!=NULL) cursor_[0]=cursor_line_[0]->ev; + cursor_line_[1]=linked_list_[1]; + first_line_[1]=cursor_line_[1]; + if (cursor_line_[1]!=NULL) cursor_[1]=cursor_line_[1]->ev; + + if (linked_list==NULL) + { + cursor_line=NULL; + cursor=NULL; + first_line=NULL; + } + else + { + cursor_line=linked_list; + cursor=cursor_line->ev; + first_line=linked_list; + } + + nvisiblelines=visibleHeight()/qfmetr->lineSpacing(); + if (nlines>nvisiblelines) + resizeContents(maxX[(typeoftextevents==1)?0:1],maxY[(typeoftextevents==1)?0:1]); + else + resizeContents(0,0); + + + setContentsPos(0,0); + viewport()->repaint(true); +} + +void KDisplayText::PaintIn(int type) +{ + bool paint=false; + if (type!=typeoftextevents) + { + int idx=(type==1)?0:1; + if (cursor_[idx]==NULL) return; + cursor_[idx]=cursor_[idx]->next; + while ((cursor_[idx]==NULL)&&(cursor_line_[idx]!=NULL)) + { + cursor_line_[idx]=cursor_line_[idx]->next; + if (cursor_line_[idx]!=NULL) + { + cursor_[idx]=cursor_line_[idx]->ev; + if ((cursor_line_[idx]->num>first_line_[idx]->num+NUMPREVLINES) + &&(cursor_line_[idx]->num<first_line_[idx]->num+nvisiblelines+1)) + if ((first_line_[idx]!=NULL)&&(first_line_[idx]->num+nvisiblelines<=nlines_[idx])) first_line_[idx]=first_line_[idx]->next; + } + } + return; + } + + if ((cursor==NULL)||(cursor_line==NULL)) + { + printf("KDispT : cursor == NULL !!!\n"); + return; + } + + kdispt_ev *tmp=cursor; + if (cursor->spev->type==typeoftextevents) + { +// int x,y; +// contentsToViewport(cursor->xpos,cursor_line->ypos,x,y); + + cursor=cursor->next; + paint=true; + + } + else + cursor=cursor->next; + + + while ((cursor==NULL)&&(cursor_line!=NULL)) + { + cursor_line=cursor_line->next; + if (cursor_line!=NULL) + { + cursor=cursor_line->ev; + if ((cursor_line->ypos>contentsY()+(visibleHeight()*5/8))&& + (cursor_line->ypos<contentsY()+visibleHeight()+autoscrollv)) + { + bool b=(autoscrollv==0); + autoscrollv+=qfmetr->lineSpacing(); + if (b) startTimer(100); + else { + killTimers(); + startTimer(100/(autoscrollv/qfmetr->lineSpacing()+1)); + } + } +// scrollBy(0,qfmetr->lineSpacing()); + } + } + if (paint) repaintContents(tmp->r); +} + +void KDisplayText::gotomsec(ulong i) +{ + int notidx=(typeoftextevents==1)?1:0; + + if (linked_list_[notidx]!=NULL) + { + cursor_line_[notidx]=linked_list_[notidx]; + first_line_[notidx]=cursor_line_[notidx]; + cursor_[notidx]=cursor_line_[notidx]->ev; + while ((cursor_line_[notidx]!=NULL)&&(cursor_[notidx]->spev->absmilliseconds<i)) + { + cursor_[notidx]=cursor_[notidx]->next; + while ((cursor_[notidx]==NULL)&&(cursor_line_[notidx]!=NULL)) + { + cursor_line_[notidx]=cursor_line_[notidx]->next; + if (cursor_line_[notidx]!=NULL) + { + cursor_[notidx]=cursor_line_[notidx]->ev; + if ((cursor_line_[notidx]->num>first_line_[notidx]->num+NUMPREVLINES) + &&(cursor_line_[notidx]->num<first_line_[notidx]->num+nvisiblelines+1)) + if ((first_line_[notidx]!=NULL)&&(first_line_[notidx]->num+nvisiblelines<=nlines_[notidx])) first_line_[notidx]=first_line_[notidx]->next; + } + } + } + } + + if (linked_list!=NULL) + { + cursor_line=linked_list; + cursor=cursor_line->ev; + first_line=linked_list; + while ((cursor_line!=NULL)&&(cursor->spev->absmilliseconds<i)) + { + cursor=cursor->next; + while ((cursor==NULL)&&(cursor_line!=NULL)) + { + cursor_line=cursor_line->next; + if (cursor_line!=NULL) + { + cursor=cursor_line->ev; + if ((cursor_line->num>first_line->num+NUMPREVLINES) + &&(cursor_line->num<first_line->num+nvisiblelines+1)) + if ((first_line!=NULL)&&(first_line->num+nvisiblelines<=nlines)) first_line=first_line->next; + } + } + + + } + + killTimers(); + autoscrollv=0; + setContentsPos(0,first_line->ypos); + viewport()->repaint(); + + } +} + +QFont *KDisplayText::getFont(void) +{ + return qtextfont; +} + +void KDisplayText::fontChanged(void) +{ + KConfig *kcfg=KGlobal::instance()->config(); + kcfg->setGroup("KMid"); + QFont *qtextfontdefault=new QFont(*qtextfont); + delete qtextfont; + qtextfont=new QFont(kcfg->readFontEntry("KaraokeFont",qtextfontdefault)); + delete qtextfontdefault; + qfmetr=new QFontMetrics(*qtextfont); + calculatePositions(); + nvisiblelines=height()/qfmetr->lineSpacing(); + viewport()->repaint(TRUE); +} + +void KDisplayText::ChangeTypeOfTextEvents(int type) +{ + int idxold=(typeoftextevents==1)?0:1; + int idxnew=(type==1)?0:1; + cursor_line_[idxold]=cursor_line; + first_line_[idxold]=first_line; + cursor_[idxold]=cursor; + linked_list=linked_list_[idxnew]; + cursor_line=cursor_line_[idxnew]; + first_line=first_line_[idxnew]; + cursor=cursor_[idxnew]; + nlines=nlines_[idxnew]; + typeoftextevents=type; + if (first_line!=NULL) + { + nvisiblelines=height()/qfmetr->lineSpacing(); + if (nlines>nvisiblelines) + resizeContents(maxX[(typeoftextevents==1)?0:1],maxY[(typeoftextevents==1)?0:1]); + else + resizeContents(0,0); + + setContentsPos(0,first_line->ypos); + } + viewport()->repaint(TRUE); +} + +int KDisplayText::ChooseTypeOfTextEvents(void) +{ + return (nlines_[0]>nlines_[1])? 1 : 5; +} + +void KDisplayText::ScrollDown() +{ + scrollBy(0,2/**qfmetr->lineSpacing()*/); +} + +void KDisplayText::ScrollUp() +{ + scrollBy(0,-2/**qfmetr->lineSpacing()*/); +} + +void KDisplayText::ScrollPageDown() +{ + scrollBy(0,nvisiblelines*qfmetr->lineSpacing()); +} + +void KDisplayText::ScrollPageUp() +{ + scrollBy(0,-nvisiblelines*qfmetr->lineSpacing()); +} + +void KDisplayText::saveLyrics(FILE *fh) +{ + kdispt_line *Lptr=linked_list_[(typeoftextevents==1)? 0:1]; + while (Lptr!=NULL) + { + kdispt_ev *Cptr=Lptr->ev; + if (Cptr!=NULL) + { + if (strcmp(Cptr->spev->text,"")!=0) + if (IsLineFeed(Cptr->spev->text[0],Cptr->spev->type)) + fputs(&Cptr->spev->text[1],fh); + else + fputs(Cptr->spev->text,fh); + Cptr=Cptr->next; + } + while (Cptr!=NULL) + { + fputs(Cptr->spev->text,fh); + Cptr=Cptr->next; + } + fputs("\n",fh); + Lptr=Lptr->next; + } +} + +void KDisplayText::timerEvent(QTimerEvent *e) +{ + int dy; + if (autoscrollv>0) + { + dy=2+autoscrollv/50; + scrollBy(0,dy); + autoscrollv-=dy; + if (autoscrollv<0) + { + killTimer(e->timerId()); + autoscrollv=0; + } + } + else + if (autoscrollv<0) + { +// dy=(autoscrollv<-2*qfmetr->lineSpacing())?-7:-2; + dy=-2+autoscrollv/50; + scrollBy(0,dy); + autoscrollv-=dy; + if (autoscrollv>0) + { + killTimer(e->timerId()); + autoscrollv=0; + } + } + else + killTimer(e->timerId()); + +} + +void KDisplayText::setLyricsEncoding(const QString &enc) +{ + QTextCodec *newcodec; + if (enc.isEmpty()) + newcodec=KGlobal::locale()->codecForEncoding(); + else + newcodec=QTextCodec::codecForName(enc.latin1()); + + if (newcodec!=lyrics_codec) + { + if (newcodec) + { + lyrics_codec=newcodec; + fontChanged(); + } + } +} + +#include "kdisptext.moc" diff --git a/kmid/kdisptext.h b/kmid/kdisptext.h new file mode 100644 index 00000000..e47026c6 --- /dev/null +++ b/kmid/kdisptext.h @@ -0,0 +1,125 @@ +/************************************************************************** + + kdisptext.h - The widget that displays the karaoke/lyrics text + Copyright (C) 1997,98 Antonio Larrosa Jimenez + + 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. + + Send comments and bug fixes to larrosa@kde.org + or to Antonio Larrosa, Rio Arnoya, 10 5B, 29006 Malaga, Spain + +***************************************************************************/ +#ifndef _kdisptext_h_ +#define _kdisptext_h_ + +#include <qwidget.h> +#include <qscrollview.h> +#include <libkmid/player.h> + +struct kdispt_ev +{ + SpecialEvent *spev; + int xpos; + class QRect r; + kdispt_ev *next; +}; + +struct kdispt_line +{ + kdispt_ev *ev; + int num; + int ypos; + kdispt_line *next; +}; + +class QFont; +class QFontMetrics; +class QScrollBar; + +class KDisplayText : public QScrollView +{ + Q_OBJECT +private: + QTextCodec *lyrics_codec; + + QFontMetrics *qfmetr; + QFont *qtextfont; + + int typeoftextevents; + + kdispt_line *linked_list_[2]; + int nlines_[2]; + kdispt_line *first_line_[2]; + kdispt_line *cursor_line_[2]; + kdispt_ev *cursor_[2]; + + kdispt_line *linked_list; + kdispt_line *cursor_line; + kdispt_ev *cursor; + + kdispt_line *first_line; // Pointer to first text at first visible line + + int nlines; // Total number of lines + int nvisiblelines; // Number of visible lines + + void RemoveLine(kdispt_line *tmpl); + void RemoveLinkedList(void); + + int IsLineFeed(char c,int type=0); + virtual void drawContents(QPainter *qpaint,int clipx,int clipy,int clipw,int cliph); + + kdispt_line * searchYOffset(int y, kdispt_line *start); + + int maxX[2]; + int maxY[2]; + int autoscrollv; + +protected: + virtual void resizeEvent(QResizeEvent *qre); + virtual void timerEvent(QTimerEvent *e); + +public: + KDisplayText(QWidget *parent,const char *name); + virtual ~KDisplayText(); + + void ClearEv(bool totally=true); + void AddEv(SpecialEvent *ev); + void calculatePositions(void); + + void CursorToHome(void); + + void ChangeTypeOfTextEvents(int type); + int ChooseTypeOfTextEvents(void); + void PaintIn(int type); + void gotomsec(ulong i); + + QFont *getFont(void); + void fontChanged(void); + + void saveLyrics(FILE *fh); + + void setLyricsEncoding(const QString &enc); + +// QSize sizeHint(); + +public slots: + void ScrollDown(); + void ScrollUp(); + void ScrollPageDown(); + void ScrollPageUp(); + +}; + +#endif diff --git a/kmid/keyboard.xpm b/kmid/keyboard.xpm new file mode 100644 index 00000000..9859e3a7 --- /dev/null +++ b/kmid/keyboard.xpm @@ -0,0 +1,50 @@ +/* XPM */ +static char * keyboard_xpm[] = { +"63 45 2 1", +" c #000000000000", +". c #FFFFFFFFFFFF", +" ", +"..... .. ..... ..... .. .. ..... ", +"..... . .. . ..... ..... . .. . .. . ..... ", +"..... . .. . ..... ..... . .. . .. . ..... ", +"..... . .. . ..... ..... . .. . .. . ..... ", +"..... . .. . ..... ..... . .. . .. . ..... ", +"..... . .. . ..... ..... . .. . .. . ..... ", +"..... . .. . ..... ..... . .. . .. . ..... ", +"..... . .. . ..... ..... . .. . .. . ..... ", +"..... . .. . ..... ..... . .. . .. . ..... ", +"..... . .. . ..... ..... . .. . .. . ..... ", +"..... . .. . ..... ..... . .. . .. . ..... ", +"..... . .. . ..... ..... . .. . .. . ..... ", +"..... . .. . ..... ..... . .. . .. . ..... ", +"..... . .. . ..... ..... . .. . .. . ..... ", +"..... . .. . ..... ..... . .. . .. . ..... ", +"..... . .. . ..... ..... . .. . .. . ..... ", +"..... . .. . ..... ..... . .. . .. . ..... ", +"..... . .. . ..... ..... . .. . .. . ..... ", +"..... . .. . ..... ..... . .. . .. . ..... ", +"..... . .. . ..... ..... . .. . .. . ..... ", +"..... . .. . ..... ..... . .. . .. . ..... ", +"..... . .. . ..... ..... . .. . .. . ..... ", +"..... . .. . ..... ..... . .. . .. . ..... ", +"..... . .. . ..... ..... . .. . .. . ..... ", +"..... .... .. .... ..... ..... .... .. .... .. .... ..... ", +"..... .. ..... ..... .. .. ..... ", +"...... .... ...... ...... .... .... ...... ", +"........ ........ ........ ........ ........ ........ ........ ", +"........ ........ ........ ........ ........ ........ ........ ", +"........ ........ ........ ........ ........ ........ ........ ", +"........ ........ ........ ........ ........ ........ ........ ", +"........ ........ ........ ........ ........ ........ ........ ", +"........ ........ ........ ........ ........ ........ ........ ", +"........ ........ ........ ........ ........ ........ ........ ", +"........ ........ ........ ........ ........ ........ ........ ", +"........ ........ ........ ........ ........ ........ ........ ", +"........ ........ ........ ........ ........ ........ ........ ", +"........ ........ ........ ........ ........ ........ ........ ", +"........ ........ ........ ........ ........ ........ ........ ", +"........ ........ ........ ........ ........ ........ ........ ", +"........ ........ ........ ........ ........ ........ ........ ", +"........ ........ ........ ........ ........ ........ ........ ", +" ", +" "}; diff --git a/kmid/klcdnumber.cpp b/kmid/klcdnumber.cpp new file mode 100644 index 00000000..190d8da4 --- /dev/null +++ b/kmid/klcdnumber.cpp @@ -0,0 +1,339 @@ +/************************************************************************** + + klcdnumber.cpp - The KLCDNumber widget (displays a lcd number) + Copyright (C) 1998 Antonio Larrosa Jimenez + + 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. + + Send comments and bug fixes to larrosa@kde.org + or to Antonio Larrosa, Rio Arnoya, 10 5B, 29006 Malaga, Spain + +***************************************************************************/ +#include "klcdnumber.h" +#include <qpainter.h> +#include <stdio.h> +#include "ktrianglebutton.h" + +#define BUTTONWIDTH 9 + +KLCDNumber::KLCDNumber(int _numDigits,QWidget *parent,const char *name) + : QWidget(parent,name) +{ + initDigits(); + setUserChangeValue=false; + numDigits=_numDigits; + value=0; + minValue=0; + maxValue=1000; + oldvalue=-1; + // setPalette( QPalette (QColor(0,0,0))); + upBtn=NULL; + downBtn=NULL; + setUserDefaultValue=false; + doubleclicked=false; + setLCDBackgroundColor(0,0,0); + setLCDColor(100,255,100); +} + +KLCDNumber::KLCDNumber(bool _setUserChangeValue,int _numDigits,QWidget *parent,const char *name) + : QWidget(parent,name) +{ + initDigits(); + setUserChangeValue=_setUserChangeValue; + numDigits=_numDigits; + value=0; + minValue=0; + maxValue=1000; + oldvalue=-1; +// setBackgroundColor(QColor(0,0,0)); +// setPalette( QPalette (QColor(0,0,0))); + upBtn=NULL; + downBtn=NULL; + setUserDefaultValue=false; + doubleclicked=false; + setLCDBackgroundColor(0,0,0); + setLCDColor(100,255,100); + if (setUserChangeValue) + { + upBtn=new KTriangleButton(KTriangleButton::Right,this,"Up"); + downBtn=new KTriangleButton(KTriangleButton::Left,this,"Down"); + upBtn->setGeometry(width()-BUTTONWIDTH,0,BUTTONWIDTH,height()); + downBtn->setGeometry(0,0,BUTTONWIDTH,height()); + connect(upBtn,SIGNAL(clicked()),this,SLOT(increaseValue())); + connect(downBtn,SIGNAL(clicked()),this,SLOT(decreaseValue())); + connect(upBtn,SIGNAL(clickedQuickly()),this,SLOT(increaseValueFast())); + connect(downBtn,SIGNAL(clickedQuickly()),this,SLOT(decreaseValueFast())); + }; +} + +void KLCDNumber::initDigits (void) +{ +Digit[0] = digit(true,true,true,false,true,true,true); +Digit[1] = digit(false,false,true,false,false,true,false); +Digit[2] = digit(true,false,true,true,true,false,true); +Digit[3] = digit(true,false,true,true,false,true,true); +Digit[4] = digit(false,true,true,true,false,true,false); +Digit[5] = digit(true,true,false,true,false,true,true); +Digit[6] = digit(true,true,false,true,true,true,true); +Digit[7] = digit(true,false,true,false,false,true,false); +Digit[8] = digit(true,true,true,true,true,true,true); +Digit[9] = digit(true,true,true,true,false,true,true); +Digit[10] = digit(false,false,false,false,false,false,false); +} + +void KLCDNumber::resizeEvent ( QResizeEvent *) +{ + if (setUserChangeValue) + { + upBtn->setGeometry(width()-BUTTONWIDTH,0,BUTTONWIDTH,height()); + downBtn->setGeometry(0,0,BUTTONWIDTH,height()); + } +} + +void KLCDNumber::drawVerticalBar(QPainter *qpaint,int x,int y,int w,int h,int d) +{ + /* If d is 0 it means that it is a bar on the left and if 1 it is on the right */ + /* + |\ /| + | | | | + | | = 0 1 = | | + | | | | + |/ \| + */ + + y++; + h-=2; + if (d==0) + { + for (int i=x;i<x+w;i++) + { + qpaint->drawLine(i,y,i,y+h); + y++; + h-=2; + } + } else { + for (int i=x+w;i>x;i--) + { + qpaint->drawLine(i,y,i,y+h); + y++; + h-=2; + } + } +} + +void KLCDNumber::drawHorizBar(QPainter *qpaint,int x,int y,int w,int h,int d) +{ + // 0 is upper, 1 is bottom and 2 is the middle bar. + x++; + w-=3; + if (d==0) + { + for (int i=y;i<y+h;i++) + { + qpaint->drawLine(x,i,x+w,i); + x++; + w-=2; + } + } + else if (d==1) + { + for (int i=y+h;i>y;i--) + { + qpaint->drawLine(x,i,x+w,i); + x++; + w-=2; + } + } + else + { + for (int i=0;i<=h/2;i++) + { + qpaint->drawLine(x,y-i,x+w,y-i); + qpaint->drawLine(x,y+i,x+w,y+i); + x++; + w-=2; + } + + }; + +} + +void KLCDNumber::drawDigit(QPainter *qpaint,int x,int y,int w,int h,digit d) +{ +if (d.nw) drawVerticalBar(qpaint,x,y,w/5,h/2,0); +if (d.ne) drawVerticalBar(qpaint,x+w*4/5,y,w/5,h/2,1); +if (d.sw) drawVerticalBar(qpaint,x,y+h/2,w/5,h/2,0); +if (d.se) drawVerticalBar(qpaint,x+w*4/5,y+h/2,w/5,h/2,1); +if (d.up) drawHorizBar (qpaint,x,y,w,w/5,0); +if (d.bt) drawHorizBar (qpaint,x,y+h-w/5,w,w/5,1); +if (d.md) drawHorizBar (qpaint,x,y+h/2,w,w/5,2); +} + + +void KLCDNumber::setValue(double v) +{ + oldvalue=value; + if (v<minValue) + value=minValue; + else if (v>maxValue) + value=maxValue; + else + value=v; + +} + +void KLCDNumber::display (double v) +{ + setValue(v); + repaint(FALSE); +} + +void KLCDNumber::display (int v) +{ + display((double)v); +} + + +void KLCDNumber::paintEvent ( QPaintEvent * ) +{ + QPainter qpaint(this); + qpaint.fillRect(0,0,width(),height(),backgcolor); + qpaint.setPen(LCDcolor); + + QString numStr; + numStr.setNum((int) value); + numStr = numStr.rightJustify( numDigits, ' ', true); + + int dx,dy,dw,dh; + if (setUserChangeValue) + { + dx=BUTTONWIDTH; + dy=height()/10; + dh=height()-dy*2; + dw=(width()-(BUTTONWIDTH*2))/numDigits; + } else + { + dx=0; + dy=height()/10; + dh=height()-dy*2; + dw=width()/numDigits; + }; + int sep=dw/10; + + for(int i=0; i < numDigits; i++) + { + char dig = numStr[i].latin1(); + if ((dig>='0')&&(dig<='9')) + drawDigit(&qpaint,dx+sep,dy,dw-sep*2,dh,Digit[dig-'0']); + else + drawDigit(&qpaint,dx+sep,dy,dw-sep*2,dh,KLCDNumber::Digit[10]); + dx+=dw; + }; +} + +void KLCDNumber::setUserSetDefaultValue(bool _userSetDefaultValue) +{ + if (setUserDefaultValue!=_userSetDefaultValue) + { + setUserDefaultValue=_userSetDefaultValue; + /* if (setUserDefaultValue) + connect(); + else + disconnect(); + */ + } + +} + +void KLCDNumber::setDefaultValue(double v) +{ + defaultValue=v; +} + + +void KLCDNumber::decreaseValue() +{ + display( value-1 ); + emit valueChanged( value ); +} + +void KLCDNumber::increaseValue() +{ + display( value+1 ); + emit valueChanged( value ); +} + +void KLCDNumber::decreaseValueFast() +{ + display( value-1 ); +} + +void KLCDNumber::increaseValueFast() +{ + display( value+1 ); +} + +void KLCDNumber::mouseDoubleClickEvent (QMouseEvent *) +{ + doubleclicked=true; + defaultValueClicked(); +} + +void KLCDNumber::mousePressEvent (QMouseEvent *e) +{ + startTimer(200); + QWidget::mousePressEvent(e); +} + +void KLCDNumber::timerEvent(QTimerEvent *) +{ + killTimers(); + doubleclicked=false; + +} + + +void KLCDNumber::defaultValueClicked() +{ + if (setUserDefaultValue) + { + display( defaultValue ); + emit valueChanged( value ); + } +} + +void KLCDNumber::setLCDBackgroundColor(int r,int g,int b) +{ + backgcolor=QColor(r,g,b); + repaint(FALSE); +} + +void KLCDNumber::setLCDColor(int r,int g,int b) +{ + LCDcolor=QColor(r,g,b); + repaint(FALSE); +} + +void KLCDNumber::setRange(double min, double max) +{ + minValue=min; + maxValue=max; +} + +QSize KLCDNumber::sizeHint() +{ + return QSize(83,28); +} +#include "klcdnumber.moc" diff --git a/kmid/klcdnumber.h b/kmid/klcdnumber.h new file mode 100644 index 00000000..0359e472 --- /dev/null +++ b/kmid/klcdnumber.h @@ -0,0 +1,153 @@ +/************************************************************************** + + klcdnumber.h - The KLCDNumber widget (displays a lcd number) + Copyright (C) 1998 Antonio Larrosa Jimenez + + 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. + + Send comments and bug fixes to larrosa@kde.org + or to Antonio Larrosa, Rio Arnoya, 10 5B, 29006 Malaga, Spain + +***************************************************************************/ +#ifndef _klcdnumber_h_ +#define _klcdnumber_h_ + +#include <qwidget.h> + +class QPainter; +class KTriangleButton; +class QColor; + +class KLCDNumber : public QWidget +{ + Q_OBJECT +protected: + class digit { +public: + digit() + : up(false), nw(false), ne(false), md(false), + sw(false), se(false), bt(false) { } + digit( bool _up, bool _nw, bool _ne, + bool _md, bool _sw, bool _se, bool _bt) + : up(_up), nw(_nw), ne(_ne), md(_md), + sw(_sw), se(_se), bt(_bt) { } + bool up; + bool nw; + bool ne; + bool md; + bool sw; + bool se; + bool bt; + }; + /* + up + --- + nw| |ne + |___|<------ md + | | + sw|___|se + bt + */ + + + KLCDNumber::digit Digit[11]; +/* +={ + / 0 / {true,true,true,false,true,true,true}, + / 1 / {false,false,true,false,false,true,false}, + / 2 / {true,false,true,true,true,false,true}, + / 3 / {true,false,true,true,false,true,true}, + / 4 / {false,true,true,true,false,true,false}, + / 5 / {true,true,false,true,false,true,true}, + / 6 / {true,true,false,true,true,true,true}, + / 7 / {true,false,true,false,false,true,false}, + / 8 / {true,true,true,true,true,true,true}, + / 9 / {true,true,true,true,false,true,true}, + / / {false,false,false,false,false,false,false} + };*/ + + int numDigits; + bool setUserChangeValue; + bool setUserDefaultValue; + bool doubleclicked; + + QColor backgcolor; + QColor LCDcolor; + + double value; + double oldvalue; + double defaultValue; + + double minValue; + double maxValue; + + void drawVerticalBar(QPainter *qpaint,int x,int y,int w,int h,int d); + void drawHorizBar(QPainter *qpaint,int x,int y,int w,int h,int d); + void drawDigit(QPainter *qpaint,int x,int y,int w,int h,digit d); + + void initDigits(void); + +public: + KLCDNumber(int _numDigits,QWidget *parent,const char *name); + KLCDNumber(bool _setUserChangeValue,int _numDigits,QWidget *parent,const char *name); + + void setUserSetDefaultValue(bool _userSetDefaultValue); + void setDefaultValue(double v); + + void setValue(double v); + double getValue(void) { return value; }; + double getOldValue(void) { return oldvalue; }; + + double getMinValue(void) { return minValue;}; + double getMaxValue(void) { return maxValue;}; + void setRange(double min, double max); + + void setLCDBackgroundColor (int r,int g,int b); + void setLCDColor (int r,int g,int b); + + void display (int v); + void display (double v); + + QSize sizeHint (); +// QSizePolicy sizePolicy(); + +protected: + + virtual void paintEvent ( QPaintEvent *e ); + virtual void resizeEvent ( QResizeEvent *e); + virtual void mouseDoubleClickEvent (QMouseEvent *e); + virtual void mousePressEvent (QMouseEvent *e); + virtual void timerEvent(QTimerEvent *e); + void defaultValueClicked(); + + KTriangleButton *downBtn; + KTriangleButton *upBtn; + + + +public slots: + + void decreaseValue(); + void increaseValue(); + void decreaseValueFast(); + void increaseValueFast(); + +signals: + + void valueChanged(double v); + +}; + +#endif diff --git a/kmid/kmid.desktop b/kmid/kmid.desktop new file mode 100644 index 00000000..3920b855 --- /dev/null +++ b/kmid/kmid.desktop @@ -0,0 +1,88 @@ +[Desktop Entry] +Name=KMid +Name[af]=Kmid +Name[bn]=কে-মিড +Name[eo]=MIDI-ludilo +Name[hi]=के-मिड +Name[ne]=केडीई मिड +Name[sv]=Kmid +Name[tr]=Kmid +Name[zh_HK]=KMidi +Name[zh_TW]=KMid 播放器 +Name[zu]=KMidi +MimeType=audio/x-karaoke;audio/x-midi;audio/midi; +GenericName=Midi/Karaoke Player +GenericName[af]=Midi/Kareokie Speler +GenericName[ar]=مشغل Midi/Karaoke +GenericName[bg]=Midi/Karaoke плеър +GenericName[br]=C'hoarier Midi/Karaoke +GenericName[bs]=Preglednik Midi/Karaoke datoteka +GenericName[ca]=Reproductor Midi/Karaoke +GenericName[cs]=Přehrávač Midi/Karaoke +GenericName[cy]=Chwaraewr Midi/Karaoke +GenericName[da]=Midi/Karaoke-afspiller +GenericName[de]=Midi/Karaoke-Programm +GenericName[el]=Αναπαραγωγέας Midi/Karaoke +GenericName[eo]=Ludilo por Midi/Karaoko-dosieroj +GenericName[es]=Un reproductor MIDI/Karaoke +GenericName[et]=Midi/karaoke mängija +GenericName[eu]=Midi/Karaoke erreproduzigailua +GenericName[fa]=پخشکنندۀ Midi/Karaoke +GenericName[fi]=Midi/Karaokesoitin +GenericName[fr]=Platine MIDI / Karaoké +GenericName[ga]=Seinnteoir Midi/Karaoke +GenericName[gl]=Reproductor de Midi/Karaoke +GenericName[he]=נגן MIDI/קריוקי +GenericName[hi]=मिडी/कराओके प्लेयर +GenericName[hr]=Midi/Karaoke player +GenericName[hu]=MIDI/Karaoke-lejátszó +GenericName[is]=Midi / Karaoke spilari +GenericName[it]=Lettore MIDI/Karaoke +GenericName[ja]=Midi/カラオケプレーヤ +GenericName[kk]=Midi/Караоке ойнатқышы +GenericName[km]=កម្មវិធីចាក់ Midi/ខារ៉ាអូខេ +GenericName[ko]=미디/노래방 재생기 +GenericName[lt]=Midi/Karaoke grotuvas +GenericName[lv]=Midi/Karaoke Atskaņotājs +GenericName[mk]=Midi/Karaoke изведувач +GenericName[ms]=Pemain Midi/Karaoke +GenericName[nb]=Midi-/karaokespiller +GenericName[nds]=Midi-/Karaoke-Afspeler +GenericName[ne]=मिडि/कारावके प्लेयर +GenericName[nl]=Midi/karaokespeler +GenericName[nn]=Midi-/karaoke-spelar +GenericName[pl]=Odtwarzacz Midi/Karaoke +GenericName[pt]=Leitor de MIDI/Karaoke +GenericName[pt_BR]=Reprodutor de Midi/Karaokê +GenericName[ro]=Program de redare MIDI/Karaoke +GenericName[ru]=Проигрыватель midi/караоке +GenericName[se]=Midi-/karaoke-čuojaheaddji +GenericName[sk]=Prehrávač Midi/Karaoke +GenericName[sl]=Predvajalnik datotek MIDI/Karaoke +GenericName[sr]=MIDI/караока плејер +GenericName[sr@Latn]=MIDI/karaoka plejer +GenericName[sv]=Midi/Karaoke-spelare +GenericName[ta]=ஒரு மிடி/கரயோக்கே இயக்கி +GenericName[tg]=Бозингари Midi/Karaoke +GenericName[th]=โปรแกรมเล่นแฟ้มมิดี้/คาราโอเกะ +GenericName[tr]=Midi ve Karaoke Yürütücü +GenericName[uk]=Програвач Midi/Karaoke +GenericName[uz]=Midi/Karaoki pleyer +GenericName[uz@cyrillic]=Midi/Караоки плейер +GenericName[ven]=Midi/Tshitambi tsha Karaoke +GenericName[xh]=Umdlali we Midi/Karaoke +GenericName[zh_CN]=Midi/卡拉 OK 播放器 +GenericName[zh_HK]=Midi/卡拉OK 播放器 +GenericName[zh_TW]=Midi/卡拉OK播放器 +GenericName[zu]=Umdlali weMidi/Karaoke +Exec=kmid %u +Icon=kmid +Path= +DocPath=kmid/index.html +Type=Application +Terminal=false +ServiceTypes=Browser/View +X-KDE-Library=libkmidpart +X-KDE-StartupNotify=true +X-DCOP-ServiceType=Multi +Categories=Qt;KDE;AudioVideo;X-KDE-More; diff --git a/kmid/kmid.lsm b/kmid/kmid.lsm new file mode 100644 index 00000000..bfae2aa6 --- /dev/null +++ b/kmid/kmid.lsm @@ -0,0 +1,22 @@ +Begin3 +Title: kmid +Version: 2.0 +Entered-date: 30/04/2001 +Description: A midi/karaoke player with a very friendly interface. + Main features of kmid : + - Shows the text of karaoke files changing its color synchronized with music + - Use external synths, fm, awe or gus cards + - Has midi maps to allow using old keyboards with GM midi/karaoke files + - Stores an unlimited number of collections (also called playlists) + - Shows in a keyboard the notes played by each instrument (at realtime). + - Allows to change the tempo +Keywords: mid kar player midi karaoke KDE X11 Qt kmid fm awe gus synth +Author: larrosa@kde.org (Antonio Larrosa Jimenez) +Maintained-by: larrosa@kde.org (Antonio Larrosa Jimenez) +Primary-site: http://perso.wanadoo.es/antlarr/kmid.html +Original-site: http://perso.wanadoo.es/antlarr/kmid.html +Alternate-site: ftp://ftp.kde.org/pub/kde/apps/multimedia +Platform: Linux, BSD and every OS in which OSS works, needs Qt 1.3, + X11 and the KDE libs +Copying-policy: GPL +End diff --git a/kmid/kmid.spec b/kmid/kmid.spec new file mode 100644 index 00000000..959ce342 --- /dev/null +++ b/kmid/kmid.spec @@ -0,0 +1,62 @@ +Summary: Play midi/karaoke files and show lyrics. Support External synths, AWE, GUS, and FM devices. For X11/KDE +Name: kmid +Version: 1.2 +Release: 1 +Copyright: GPL +Group: X11/K Desktop Environment/Multimedia +Source: kmid-1.2.tar.gz +Requires: qt >= 1.3 , kdelibs + +%description +KMid is a midi/karaoke file player, with configurable midi mapper, +real Session Management, drag & drop, customizable fonts, etc. +It has a very nice interface which let you easily follow the tune while +changing the color of the lyrics. +It supports output through external synthesizers, AWE, FM and GUS cards. +It also has a keyboard view to see the notes played by each instrument + +%prep +%setup + +%build +export KDEDIR=/opt/kde +./configure +make all + +%install +export KDEDIR=/opt/kde +make install + +%files +%doc kmid/README kmid/COPYING kmid/PEOPLE kmid/kmid.lsm kmid/ChangeLog + +/opt/kde/bin/kmid +/opt/kde/share/doc/HTML/en/kmid +/opt/kde/share/doc/HTML/es/kmid +/opt/kde/share/icons/kmid.xpm +/opt/kde/share/icons/mini/kmid.xpm +/opt/kde/share/applnk/Multimedia/kmid.kdelnk +/opt/kde/share/mimelnk/audio/x-karaoke.kdelnk +/opt/kde/share/apps/kmid/toolbar +/opt/kde/share/apps/kmid/fm +/opt/kde/share/apps/kmid/maps/gm.map +/opt/kde/share/apps/kmid/maps/YamahaPSS790.map +/opt/kde/share/apps/kmid/maps/YamahaPSR500.map +/opt/kde/share/apps/kmid/OFortuna.kar +/opt/kde/share/apps/kmid/StopInTheNameOfLove.kar +/opt/kde/share/apps/kmid/TheGirlFromIpanema.kar +/opt/kde/share/apps/kmid/AnotherGlitchInTheCall.kar +/opt/kde/share/locale/es/LC_MESSAGES/kmid.mo +/opt/kde/share/locale/cs/LC_MESSAGES/kmid.mo +/opt/kde/share/locale/de/LC_MESSAGES/kmid.mo +/opt/kde/share/locale/fi/LC_MESSAGES/kmid.mo +/opt/kde/share/locale/hr/LC_MESSAGES/kmid.mo +/opt/kde/share/locale/pl/LC_MESSAGES/kmid.mo +/opt/kde/share/locale/pt/LC_MESSAGES/kmid.mo +/opt/kde/share/locale/sk/LC_MESSAGES/kmid.mo +/opt/kde/share/locale/eo/LC_MESSAGES/kmid.mo +/opt/kde/share/locale/no/LC_MESSAGES/kmid.mo +/opt/kde/share/locale/sv/LC_MESSAGES/kmid.mo +/opt/kde/share/locale/pt_BR/LC_MESSAGES/kmid.mo +/opt/kde/share/locale/zh_CN.GB2312/LC_MESSAGES/kmid.mo +/opt/kde/share/locale/zh_TW.Big5/LC_MESSAGES/kmid.mo diff --git a/kmid/kmidIface.h b/kmid/kmidIface.h new file mode 100644 index 00000000..75f2ca72 --- /dev/null +++ b/kmid/kmidIface.h @@ -0,0 +1,46 @@ +#ifndef _KMIDIFACE_H_ +#define _KMIDIFACE_H_ + +#include <dcopobject.h> + +class KMidIface : virtual public DCOPObject +{ + K_DCOP + +k_dcop: +// File + + virtual int openURL( const QString s )=0; + + // Song + virtual void play()=0; + virtual void pause()=0; + virtual void stop()=0; + virtual void rewind()=0; + virtual void forward()=0; + virtual void seek(int ms)=0; + virtual void prevSong()=0; + virtual void nextSong()=0; + + virtual void setSongLoop(int i)=0; + virtual void setVolume(int i)=0; + virtual void setTempo(int i)=0; +// GUI + + + virtual void setSongEncoding( int i )=0; + virtual void setLyricEvents( int i )=0; + +// Collections + virtual void setCurrentSong(int i)=0; + + virtual void setActiveCollection( int i )=0; + virtual void setCollectionPlayMode(int i)=0; + +// Midi device + + virtual void setMidiDevice(int i)=0; + +}; +#endif + diff --git a/kmid/kmid_part.cpp b/kmid/kmid_part.cpp new file mode 100644 index 00000000..98241ac1 --- /dev/null +++ b/kmid/kmid_part.cpp @@ -0,0 +1,144 @@ +#include "kmid_part.h" + +#include <kinstance.h> +#include <kiconloader.h> +#include <klocale.h> +#include <kaboutdata.h> +#include <kaction.h> +#include <qiconset.h> + +#include <kparts/partmanager.h> + +#include "kmidclient.h" +#include <qtimer.h> +#include <kdelibs_export.h> + +K_EXPORT_COMPONENT_FACTORY( libkmidpart, KMidFactory ) + +/** + * We need one static instance of the factory for our C 'main' + * function + */ +KInstance *KMidFactory::s_instance = 0L; + +KMidFactory::KMidFactory() +{ + s_instance=0L; +} + +KMidFactory::~KMidFactory() +{ + if (s_instance) + { + delete s_instance->aboutData(); + delete s_instance; + } + + s_instance = 0; +} + +KParts::Part *KMidFactory::createPartObject(QWidget *parentWidget, const char *widgetName, + QObject *parent, const char *name, const char*, + const QStringList& ) +{ + KParts::Part *obj = new KMidPart(parentWidget, widgetName, parent, name); + return obj; +} + +KAboutData *KMidFactory::aboutData() +{ + KAboutData *aboutdata = new KAboutData("kmid", "KMid", "2.0", + I18N_NOOP("MIDI/Karaoke file player"), KAboutData::License_GPL, + I18N_NOOP("(c) 1997,98,99,2000, Antonio Larrosa Jimenez"),"", + "http://perso.wanadoo.es/antlarr/kmid.html"); + aboutdata->addAuthor("Antonio Larrosa Jimenez", + I18N_NOOP("Original Developer/Maintainer"),"larrosa@kde.org", + "http://perso.wanadoo.es/antlarr/index.html"); + return aboutdata; +} + +KInstance *KMidFactory::instance() +{ + if ( !s_instance ) + s_instance = new KInstance( aboutData() ); + + return s_instance; +} + + KMidPart::KMidPart(QWidget *parentWidget, const char *widgetName, + QObject *parent, const char *name) +: KParts::ReadOnlyPart(parent, name) +{ + setInstance(KMidFactory::instance()); + + widget = new kmidClient(parentWidget, actionCollection()); + widget->show(); + widget->setFocusPolicy(QWidget::ClickFocus); + setWidget(widget); + + // create and connect our actions + (void)new KAction(i18n("Play"), "player_play", 0, this, + SLOT(slotPlay()), actionCollection(), + "play"); + + (void)new KAction(i18n("Stop"), "player_stop", 0, this, + SLOT(slotStop()), actionCollection(), + "stop"); + + (void)new KAction(i18n("Backward"), + "2leftarrow", 0, this, + SLOT(slotBackward()), actionCollection(), + "backward"); + + (void)new KAction(i18n("Forward"), + "2rightarrow", 0, this, + SLOT(slotForward()), actionCollection(), + "forward"); + + m_extension = new KMidBrowserExtension(this); + + setXMLFile("kmid_partui.rc"); + + +} + +KMidPart::~KMidPart() +{ +} + +bool KMidPart::openFile() +{ + widget->openURL(m_file); + widget->stop(); + widget->show(); + QTimer::singleShot(2000, this, SLOT(slotPlay())); + + return true; +} + +bool KMidPart::closeURL() +{ + slotStop(); + return true; +} + +void KMidPart::slotPlay() +{ + widget->stop(); + widget->play(); +} + + +void KMidPart::slotStop() +{ + widget->stop(); +} +KMidBrowserExtension::KMidBrowserExtension(KMidPart *parent) + : KParts::BrowserExtension(parent, "KMidBrowserExtension") +{ +} + +KMidBrowserExtension::~KMidBrowserExtension() +{ +} +#include "kmid_part.moc" diff --git a/kmid/kmid_part.h b/kmid/kmid_part.h new file mode 100644 index 00000000..4b02e099 --- /dev/null +++ b/kmid/kmid_part.h @@ -0,0 +1,63 @@ +#ifndef __KMIDPART_H__ +#define __KMIDPART_H__ + +#include <kparts/browserextension.h> +#include <kparts/factory.h> +#include <kdelibs_export.h> +class KAboutData; +class KInstance; +class KMidBrowserExtension; +class kmidClient; + +class KDE_EXPORT KMidFactory : public KParts::Factory +{ + Q_OBJECT + public: + KMidFactory(); + virtual ~KMidFactory(); + + virtual KParts::Part* createPartObject(QWidget *parentWidget, const char *widgetName, + QObject* parent = 0, const char* name = 0, + const char* classname = "QObject", + const QStringList &args = QStringList()); + + static KInstance *instance(); + + static KAboutData *aboutData(); + private: + static KInstance *s_instance; +}; + +class KMidPart: public KParts::ReadOnlyPart +{ + Q_OBJECT + public: + KMidPart(QWidget *parentWidget, const char *widgetName, + QObject *parent, const char *name); + virtual ~KMidPart(); + + + virtual bool closeURL(); + + protected: + virtual bool openFile(); + + protected slots: + void slotPlay(); + void slotStop(); + + private: + kmidClient *widget; + KMidBrowserExtension *m_extension; +}; + +class KMidBrowserExtension : public KParts::BrowserExtension +{ + Q_OBJECT + friend class KMidPart; + public: + KMidBrowserExtension(KMidPart *parent); + virtual ~KMidBrowserExtension(); +}; + +#endif diff --git a/kmid/kmid_partui.rc b/kmid/kmid_partui.rc new file mode 100644 index 00000000..aad5c6b2 --- /dev/null +++ b/kmid/kmid_partui.rc @@ -0,0 +1,17 @@ +<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd"> +<kpartgui name="kmid" version="2"> +<MenuBar> + <Menu name="view"> + <Action name="play"/> + <Action name="stop"/> + <Action name="backward"/> + <Action name="forward"/> + </Menu> +</MenuBar> +<ToolBar name="KMid-ToolBar"> + <Action name="play"/> + <Action name="stop"/> + <Action name="backward"/> + <Action name="forward"/> +</ToolBar> +</kpartgui> diff --git a/kmid/kmidbutton.h b/kmid/kmidbutton.h new file mode 100644 index 00000000..cda01f59 --- /dev/null +++ b/kmid/kmidbutton.h @@ -0,0 +1,32 @@ +#include <qpushbutton.h> +#include <qpainter.h> + +class KMidButton : public QPushButton +{ +protected: + + QPixmap pixmap1,pixmap2; + + virtual void drawButton(QPainter *paint) + { + if ((isOn())&&(!pixmap1.isNull())) paint->drawPixmap(0,0,pixmap1); + else if ((!isOn())&&(!pixmap2.isNull())) paint->drawPixmap(0,0,pixmap2); + }; + +public: + + KMidButton (QWidget *parent,const char *name) : QPushButton (parent,name) + { + }; + + ~KMidButton() + { + }; + + void setPixmaps(const QPixmap& p1, const QPixmap& p2) + { + pixmap1=p1; + pixmap2=p2; + }; + +}; diff --git a/kmid/kmidclient.cpp b/kmid/kmidclient.cpp new file mode 100644 index 00000000..c7dcd009 --- /dev/null +++ b/kmid/kmidclient.cpp @@ -0,0 +1,1606 @@ +/************************************************************************** + + kmidclient.cpp - The main client widget of KMid + Copyright (C) 1997,98 Antonio Larrosa Jimenez + + 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. + + Send comments and bug fixes to larrosa@kde.org + or to Antonio Larrosa, Rio Arnoya, 10 5B, 29006 Malaga, Spain + +***************************************************************************/ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/shm.h> +#include <sys/wait.h> +#include <signal.h> // kill is declared on signal.h on bsd, not sys/signal.h +#include <sys/signal.h> + +#include <qkeycode.h> +#include <qfiledialog.h> +#include <qstring.h> +#include <qlabel.h> +#include <qfile.h> +#include <qcombobox.h> +#include <qlayout.h> + +#include <kapplication.h> +#include <kcharsets.h> +#include <kconfig.h> +#include <kglobal.h> +#include <klocale.h> +#include <kmessagebox.h> +#include <kstandarddirs.h> +#include <kurl.h> +#include <kaction.h> +#include <kdebug.h> + +#include <libkmid/midimapper.h> +#include <libkmid/fmout.h> +#include <libkmid/track.h> +#include <libkmid/midispec.h> +#include <libkmid/deviceman.h> +#include <libkmid/mt32togm.h> +#include "kmidclient.h" +#include "klcdnumber.h" +#include "randomlist.h" +#include "channelview.h" +#include "channel.h" +#include "version.h" +#include "rhythmview.h" + +//#define TEMPHACK + + +kmidClient::kmidClient(QWidget *parent, KActionCollection *ac, const char *name) + : DCOPObject("KMidIface"), QWidget(parent,name) +{ + actionCollection=ac; + KConfig *cfg=kapp->config(); + cfg->setGroup("KMid"); + midifile_opened=0L; + loopsong=cfg->readNumEntry("Loop",0); + collectionplaymode=0; + collectionplaylist=0L; + channelView=0L; + noteArray=0L; + shuttingdown=false; + + KConfig *kconf=KGlobal::instance()->config(); + + kconf->setGroup("KMid"); + QString tmp2 = locateLocal("appdata", "collections"); + collectionsfile=kconf->readPathEntry("CollectionsFile",tmp2); + slman=new SLManager(); + slman->loadConfig(QFile::encodeName(collectionsfile)); + currentsl=NULL; + // currentsl=slman->getCollection(activecollection); + itsme=0; + m_kMid.pid=0; + timebar = new QSlider(0,240000,30000,60000,QSlider::Horizontal, this); + timebar->setSteps(30000,60000); + timebar->setValue(0); + connect (timebar,SIGNAL(valueChanged(int)),this,SLOT(slotSeek(int))); + + timetags = new QSliderTime(timebar,this); + timetags->setMinimumSize(timetags->sizeHint()); + + qlabelTempo= new QLabel(i18n("Tempo:"), this,"tempolabel", + QLabel::NoFrame); + + tempoLCD = new KLCDNumber( true, 3, this, "TempoLCD"); + tempoLCD->setValue(120); + tempoLCD->display(120); + currentTempo=120; + tempoLCD->setRange(3,999); + tempoLCD->setDefaultValue(120); + tempoLCD->setUserSetDefaultValue(true); + tempoLCD->setMinimumSize(tempoLCD->sizeHint()); + connect(tempoLCD,SIGNAL(valueChanged(double)),this,SLOT(slotSetTempo(double))); + + comboSongs = new QComboBox(FALSE, this,"Songs"); + connect (comboSongs,SIGNAL(activated(int)),this,SLOT(slotSelectSong(int))); + comboSongs->setMinimumWidth(200); + + comboEncodings = new QComboBox(FALSE, this, "Encodings"); + connect (comboEncodings,SIGNAL(activated(int)),this,SLOT(slotSelectEncoding(int))); + comboEncodings->insertItem(i18n("Default")); + comboEncodings->insertStringList( KGlobal::charsets()->descriptiveEncodingNames() ); + comboEncodings->setCurrentItem(0); + + rhythmview= new RhythmView( this, "RhythmView"); + rhythmview->setMaximumHeight(7); + rhythmview->setMinimumHeight(7); + + volumebar = new QSlider(0,200,10,100,QSlider::Vertical, this ); + volumebar->setSteps(10,20); + volumebar->setValue(100); + volumebar->setTickmarks(QSlider::NoMarks); + volumebar->setTickInterval(50); + connect (volumebar,SIGNAL(valueChanged(int)),this,SLOT(slotSetVolume(int))); + + visiblevolumebar=cfg->readNumEntry("ShowVolumeBar",0); + if (visiblevolumebar) volumebar->show(); + else volumebar->hide(); + + typeoftextevents=1; + kdispt=new KDisplayText( this, "KaraokeWindow"); + kdispt->show(); + + timer4timebar=new QTimer(this); + connect (timer4timebar,SIGNAL(timeout()),this,SLOT(timebarUpdate())); + timer4events=new QTimer(this); + connect (timer4events,SIGNAL(timeout()),this,SLOT(processSpecialEvent())); + + QString samplefile = + KGlobal::dirs()->findAllResources("appdata", "fm/*.o3").last(); + samplefile.truncate(samplefile.findRev('/')); + FMOut::setFMPatchesDirectory(QFile::encodeName(samplefile)); + + m_kMid.pctlsmID=shmget(IPC_PRIVATE,sizeof(PlayerController),0666 | IPC_CREAT ); + if (m_kMid.pctlsmID==-1) + { + printf("ERROR: Cannot allocate shared memory !!!\n" + "Please report to larrosa@kde.org\n"); + exit(1); + } + + m_kMid.pctl=(PlayerController *)shmat(m_kMid.pctlsmID,0L,0); + if (!m_kMid.pctl) + printf("ERROR: Cannot get shared memory !!! " + "Please report to larrosa@kde.org\n"); + m_kMid.pctl->playing=0; + m_kMid.pctl->gm=1; + m_kMid.pctl->volumepercentage=100; + m_kMid.pctl->tempo=500000; + m_kMid.pctl->ratioTempo=1.0; + for (int i=0;i<16;i++) + { + m_kMid.pctl->forcepgm[i]=0; + m_kMid.pctl->pgm[i]=0; + } + + + kconf->setGroup("KMid"); + int mididev=kconf->readNumEntry("MidiPortNumber",-1); + + midi = new DeviceManager(mididev); + midi->initManager(); + m_kMid.midi=midi; + player= new MidiPlayer(midi,m_kMid.pctl); + + kconf->setGroup("Midimapper"); + QCString qs=QFile::encodeName(kconf->readPathEntry("Loadfile","gm.map")); + +#ifdef KMidDEBUG + printf("Read Config file: %s\n",qs.data()); +#endif + setMidiMapFilename(qs.data()); + + initializing_songs=1; + kconf->setGroup("KMid"); + setActiveCollection(kconf->readNumEntry("ActiveCollection",0)); + initializing_songs=0; + + QVBoxLayout *lv=new QVBoxLayout( this ); + lv->addWidget( timebar ); + lv->addWidget( timetags ); + lv->addSpacing(5); + QHBoxLayout *lh=new QHBoxLayout( lv ); + lh->addWidget( qlabelTempo ); + lh->addWidget( tempoLCD ); + lh->addWidget( comboSongs, 6 ); + lv->addSpacing(5); + lh->addWidget( comboEncodings, 1 ); + lv->addSpacing(5); + lv->addWidget( rhythmview ); + lv->addSpacing(2); + QHBoxLayout *lh2=new QHBoxLayout( lv ); + lh2->addWidget( volumebar ); + lh2->addWidget( kdispt ); +} + +/*void kmidClient::resizeEvent(QResizeEvent *) +{ + //timebar->resize(width()-5,timebar->height()); + timebar->setGeometry(5,10,width()-5,timebar->height()); + timetags->setGeometry(5,10+timebar->height(),width()-5,timetags->getFontHeight()); + comboSongs->setGeometry(tempoLCD->x()+tempoLCD->width()+15,tempoLCD->y(),width()-(tempoLCD->x()+tempoLCD->width()+25),tempoLCD->height()); + rhythmview->setGeometry(5,10+timebar->height()+timetags->height()+5+tempoLCD->height()+2,width()-10,7); + volumebar->setGeometry(5,10+timebar->height()+timetags->height()+5+tempoLCD->height()+10,15,height()-(10+timebar->height()+timetags->height()+5+tempoLCD->height()+15)); + kdispt->setGeometry(((visiblevolumebar)?25:5),10+timebar->height()+timetags->height()+5+tempoLCD->height()+10,width()-(5+((visiblevolumebar)?25:5)),height()-(10+timebar->height()+timetags->height()+5+tempoLCD->height()+10)); +} +*/ + +kmidClient::~kmidClient() +{ + if (m_kMid.pctl->playing==1) + { + stop(); + // sleep(1); + } + + if (m_kMid.pid!=0) + { + kill(m_kMid.pid,SIGTERM); + waitpid(m_kMid.pid, 0L, 0); + m_kMid.midi->closeDev(); + m_kMid.pid=0; + } + + allNotesOff(); + + delete midifile_opened; + delete player; + delete midi; + delete [] collectionplaylist; + + saveCollections(); + delete slman; + +// Let's detach and delete shared memory + shmdt((char *)m_kMid.pctl); + shmctl(m_kMid.pctlsmID, IPC_RMID, 0L); + m_kMid.pctl=0L; +} + +// Use KURL::filename ! (David) +char *extractFilename(const char *in,char *out) +{ + char *p=(char *)in; + char *result=out; + char *filename=(char *)in; + while (*p!=0) + { + if (*p=='/') filename=p+1; + p++; + } + while (*filename!=0) + { + *out=*filename; + out++; + filename++; + } + *out=0; + return result; +} + +int kmidClient::openFile(const char *filename) +{ + m_kMid.pctl->message|=PLAYER_HALT; + stop(); + int r; + player->setGenerateBeats(true); + if ((r=player->loadSong(filename))!=0) + { + QString errormsg; + switch (r) + { + case (-1) : errormsg = + i18n("The file %1 does not exist or cannot be opened.").arg(filename); + break; + case (-2) : errormsg = + i18n("The file %1 is not a MIDI file.").arg(filename);break; + case (-3) : errormsg = + i18n("Ticks per quarter note is negative. Please send this file to larrosa@kde.org");break; + case (-4) : errormsg = + i18n("Not enough memory.");break; + case (-5) : errormsg = + i18n("This file is corrupted or not well built.");break; + case (-6) : errormsg = + i18n("%1 is not a regular file.").arg(filename);break; + default : errormsg = i18n("Unknown error message");break; + } + KMessageBox::error(this, errormsg); + // player->loadSong(midifile_opened); + if (midifile_opened) delete midifile_opened; + midifile_opened=0L; + timebar->setRange(0,240000); + timebar->setValue(0); + timetags->repaint(TRUE); + kdispt->ClearEv(); + kdispt->repaint(TRUE); + topLevelWidget()->setCaption("KMid"); + + return -1; + } + + if (midifile_opened) delete midifile_opened; + midifile_opened=new char[strlen(filename)+1]; + strcpy(midifile_opened,filename); +#ifdef KMidDEBUG + printf("TOTAL TIME: %g milliseconds\n",player->information()->millisecsTotal); +#endif + // noteArray=player->parseNotes(); + noteArray=player->noteArray(); + timebar->setRange(0,(int)(player->information()->millisecsTotal)); + timetags->repaint(TRUE); + kdispt->ClearEv(); + spev=player->specialEvents(); + while (spev) + { + if ((spev->type==1) || (spev->type==5)) + { + kdispt->AddEv(spev); + } + spev=spev->next; + } + + kdispt->calculatePositions(); + kdispt->CursorToHome(); +// kdispt->updateScrollBars(); + emit mustRechooseTextEvent(); + kdispt->repaint(TRUE); + tempoLCD->display(tempoToMetronomeTempo(m_kMid.pctl->tempo)); + currentTempo=tempoLCD->getValue(); + tempoLCD->setDefaultValue(tempoToMetronomeTempo(m_kMid.pctl->tempo)*m_kMid.pctl->ratioTempo); + + char *fn=new char[strlen(filename)+20]; + extractFilename(filename,fn); + char *capt=new char[strlen(fn)+20]; + sprintf(capt,"KMid - %s",fn); + delete fn; + topLevelWidget()->setCaption(capt); + delete capt; + + timebar->setValue(0); + return 0; +} + +int kmidClient::openURL(const QString _url) +{ + KURL u(_url); + if (!u.isValid()) {printf("Malformed URL\n");return -1;}; + + QString filename; + bool deleteFile=false; + if (!u.isLocalFile()) + { + filename = QString("/tmp/") + u.filename(); + KIO::Job *iojob = KIO::copy( u, KURL::fromPathOrURL( filename ) ); + downloaded=false; + connect( iojob, SIGNAL( result( KIO::Job *) ), this, SLOT(downloadFinished( KIO::Job * ) ) ); + + if (!downloaded) + kapp->enter_loop(); + deleteFile=true; + + } + else + { + filename=u.path(); + } + + QCString filename_8bit = QFile::encodeName(filename); + int r=-1; + if (!filename_8bit.isEmpty()) + { + r=openFile(filename_8bit.data()); + + KConfig *cfg=KGlobal::instance()->config(); + if (cfg->readBoolEntry("deleteTmpNonLocalFiles",false)) + { + unlink(filename_8bit.data()); + } + } + return r; +} + +ulong kmidClient::timeOfNextEvent(int *type) +{ + int t=0; + ulong x=0; + + + if (!channelView) + { + if ((spev)&&(spev->type!=0)) + { + t=1; + x=spev->absmilliseconds; + } + } + else + { + if (noteArray) + { + NoteArray::noteCmd *ncmd=noteArray->get(); + if (!ncmd) + { + if ((spev)&&(spev->type!=0)) + { + t=1; + x=spev->absmilliseconds; + } + } + else + { + if ((!spev)||(spev->type==0)) + { + t=2; + x=ncmd->ms; + } + else + { + if (spev->absmilliseconds<ncmd->ms) + { + t=1; + x=spev->absmilliseconds; + } + else + { + t=2; + x=ncmd->ms; + } + + } + } + } + } + + if (type) *type=t; + return x; + /* + + if (type!=NULL) *type=0; + if (channelView==NULL) + { + if ((spev!=NULL)&&(spev->type!=0)) + { + if (type!=NULL) *type=1; + return spev->absmilliseconds; + } + else return 0; + } + + if (noteArray==NULL) return 0; + noteCmd *ncmd=noteArray->get(); + if (ncmd==NULL) + { + if ((spev!=NULL)&&(spev->type!=0)) + { + if (type!=NULL) *type=1; + return spev->absmilliseconds; + } + else return 0; + } + else + { + if ((spev==NULL)||(spev->type==0)) + { + if (type!=NULL) *type=2; + return ncmd->ms; + } + else + { + if (spev->absmilliseconds<ncmd->ms) + { + if (type!=NULL) *type=1; + return spev->absmilliseconds; + } + else + { + if (type!=NULL) *type=2; + return ncmd->ms; + } + + } + } + */ +} + +void kmidClient::slotPlay() +{ + if (!player->isSongLoaded()) + { + KMessageBox::sorry(this, + i18n("You must load a file before playing it.")); + return; + } + if (m_kMid.pctl->playing==1) + { + KMessageBox::sorry(this, + i18n("A song is already being played.")); + return; + } + if (midi->checkInit()==-1) + { + KMessageBox::error(this, + i18n("Could not open /dev/sequencer.\nProbably there is another program using it.")); + return; + } + + kdispt->CursorToHome(); + m_kMid.pctl->message=0; + m_kMid.pctl->playing=0; + m_kMid.pctl->finished=0; + m_kMid.pctl->error=0; + m_kMid.pctl->SPEVplayed=0; + m_kMid.pctl->SPEVprocessed=0; +#ifdef KMidDEBUG + passcount=0; +#endif + noteArray->iteratorBegin(); + + QApplication::flushX(); + if ((m_kMid.pid=fork())==0) + { +#ifdef KMidDEBUG + printf("PlayerProcessID: %d\n",getpid()); +#endif + player->play(0,(void (*)(void))kmidOutput); +#ifdef KMidDEBUG + printf("End of child process\n"); +#endif + _exit(0); + } + m_kMid.pctl->millisecsPlayed=0; + + + spev=player->specialEvents(); +#ifdef KMidDEBUG + printf("writing SPEV\n"); + player->debugSpecialEvents(); + printf("writing SPEV(END)\n"); +#endif + + while ((m_kMid.pctl->playing==0)&&(m_kMid.pctl->error==0)) ; + + if (m_kMid.pctl->error==1) return; + beginmillisec=m_kMid.pctl->beginmillisec; + + int type; + ulong x=timeOfNextEvent(&type); + if (type!=0) + timer4events->start(x,TRUE); + + timer4timebar->start(1000); + +#ifdef KMidDEBUG + printf("PlayerProcess: %d . ParentProcessID: %d\n",m_kMid.pid,getpid()); + printf("******************************-\n"); +#endif +} + +void kmidClient::timebarUpdate() +{ + itsme=1; + if (m_kMid.pctl->playing==0) + { + timer4timebar->stop(); + } + + timeval tv; + gettimeofday(&tv, NULL); + ulong currentmillisec=tv.tv_sec*1000+tv.tv_usec/1000; + m_kMid.pctl->millisecsPlayed=(currentmillisec-beginmillisec); + + timebar->setValue((int)(m_kMid.pctl->millisecsPlayed)); + itsme=0; + if ((m_kMid.pctl->playing==0)&&(m_kMid.pctl->finished==1)) + { + waitpid(m_kMid.pid, NULL, 0); + if (loopsong) + { + play(); + return; + } + else + nextSong(); + } +} + +void kmidClient::slotSeek(int i) +{ + if (itsme) return; + + if (m_kMid.pctl->playing==0) + { + itsme=1; + timebar->setValue(0); + itsme=0; + return; + } + + if (m_kMid.pctl->paused) return; + + if (m_kMid.pid!=0) + { + kill(m_kMid.pid,SIGTERM); +#ifdef KMidDEBUG + printf("Waiting for Process %d to be killed\n",m_kMid.pid); +#endif + waitpid(m_kMid.pid, NULL, 0); + m_kMid.midi->closeDev(); + m_kMid.pid=0; + } + allNotesOff(); + + +#ifdef KMidDEBUG + printf("change Time: %d\n",i); +#endif + + timer4events->stop(); + if (channelView!=NULL) channelView->reset(0); + + moveEventPointersTo((ulong)i); + + m_kMid.pctl->playing=0; + m_kMid.pctl->OK=0; + m_kMid.pctl->error=0; + m_kMid.pctl->gotomsec=i; + m_kMid.pctl->message|=PLAYER_SETPOS; + + QApplication::flushX(); + if ((m_kMid.pid=fork())==0) + { +#ifdef KMidDEBUG + printf("Player_ProcessID: %d\n",getpid()); +#endif + + player->play(0,(void (*)(void))kmidOutput); + +#ifdef KMidDEBUG + printf("End of child process\n"); +#endif + _exit(0); + } + + while ((m_kMid.pctl->playing==0)&&(m_kMid.pctl->error==0)) ; + + if (m_kMid.pctl->error==1) return; + beginmillisec=m_kMid.pctl->beginmillisec-i; + ulong currentmillisec=m_kMid.pctl->beginmillisec; + + int type; + ulong x=timeOfNextEvent(&type); + if (type!=0) + timer4events->start(x-(currentmillisec-beginmillisec),TRUE); + + /* + if (spev==NULL) return; + ulong delaymillisec=spev->absmilliseconds-(currentmillisec-beginmillisec); + timer4events->start(delaymillisec,TRUE); + */ + + m_kMid.pctl->OK=0; +/* + tempoLCD->display(tempoToMetronomeTempo(m_kMid.pctl->tempo)); + currentTempo=tempoLCD->getValue(); + tempoLCD->setDefaultValue(tempoToMetronomeTempo(m_kMid.pctl->tempo)*m_kMid.pctl->ratioTempo); +*/ +} + +void kmidClient::moveEventPointersTo(ulong ms) +{ +#ifdef KMidDEBUG + printf("Move To: %lu\n",ms); +#endif + spev=player->specialEvents(); + + ulong tempo=(ulong)(500000 * m_kMid.pctl->ratioTempo); + int num=4; + int den=4; + + while ((spev!=NULL)&&(spev->absmilliseconds<ms)) + { + if (spev->type==3) tempo=spev->tempo; + else if (spev->type==6) {num=spev->num;den=spev->den;} + spev=spev->next; + } + tempoLCD->display(tempoToMetronomeTempo(tempo)); + currentTempo=tempoLCD->getValue(); + tempoLCD->setDefaultValue(tempoToMetronomeTempo(tempo)*m_kMid.pctl->ratioTempo); + + rhythmview->setRhythm(num,den); + + kdispt->gotomsec(ms); +// if (noteArray!=NULL) noteArray->moveIteratorTo(ms); + if (noteArray!=NULL) + { + int pgm[16]; + noteArray->moveIteratorTo(ms,pgm); + if (channelView!=NULL) + { + for (int j=0;j<16;j++) + { + if (!m_kMid.pctl->forcepgm[j]) channelView->changeInstrument(j,(m_kMid.pctl->gm==1)?(pgm[j]):(MT32toGM[pgm[j]])); + else channelView->changeInstrument(j,(m_kMid.pctl->pgm[j])); + } + } + } + + /* + if (noteArray!=NULL) + { + noteCmd *ncmd; + noteArray->iteratorBegin(); + ncmd=noteArray->get(); + while ((ncmd!=NULL)&&(ncmd->ms<ms)) + { + noteArray->next(); + ncmd=noteArray->get(); + } + } + */ +} + +void kmidClient::slotSetVolume(int i) +{ + int autochangemap=0; + if ((m_kMid.pctl->playing==1)&&(m_kMid.pctl->paused==0)) autochangemap=1; + + if (autochangemap) + { + pause(); + } + i=200-i; + m_kMid.pctl->volumepercentage=i; + + if (autochangemap) + { + pause(); + } +} + + +void kmidClient::slotPrevSong() +{ + if (currentsl==NULL) return; + if (collectionplaylist==NULL) generateCPL(); + if (collectionplaylist==NULL) return; + /* + if (collectionplaymode==0) + { + if (currentsl->getActiveSongID()==1) return; + currentsl->previous(); + } + else + { + int r; + while ((r=1+(int) ((double)(currentsl->NumberOfSongs())*rand()/(RAND_MAX+1.0)))==currentsl->getActiveSongID()) ; + + currentsl->setActiveSong(r); + } + */ + int idx=searchInCPL(currentsl->getActiveSongID()); + if (idx==0) return; + idx--; + currentsl->setActiveSong(collectionplaylist[idx]); + + if (currentsl->getActiveSongID()==-1) + { + // comboSongs->setCurrentItem(0); + // currentsl->setActiveSong(1); + return; + } + + if (m_kMid.pctl->paused) emit stopPause(); + comboSongs->setCurrentItem(currentsl->getActiveSongID()-1); + if (openURL(currentsl->getActiveSongName())==-1) return; + play(); + +} + +void kmidClient::slotNextSong() +{ + if (currentsl==NULL) return; + if (collectionplaylist==NULL) generateCPL(); + if (collectionplaylist==NULL) return; + + /*if (collectionplaymode==0) + { + if (currentsl->getActiveSongID()==currentsl->NumberOfSongs()) return; + currentsl->next(); + } + else + { + int r; + while ((r=1+(int) ((double)(currentsl->NumberOfSongs())*rand()/(RAND_MAX+1.0)))==currentsl->getActiveSongID()) ; + + #ifdef KMidDEBUG + printf("random number:%d\n",r); + #endif + currentsl->setActiveSong(r); + } + */ + int idx=searchInCPL(currentsl->getActiveSongID()); + idx++; + if (idx==currentsl->NumberOfSongs()) return; + currentsl->setActiveSong(collectionplaylist[idx]); + if (currentsl->getActiveSongID()==-1) + { + //// comboSongs->setCurrentItem(0); + // currentsl->setActiveSong(1); + return; + } + + if (m_kMid.pctl->paused) emit stopPause(); + comboSongs->setCurrentItem(currentsl->getActiveSongID()-1); + if (openURL(currentsl->getActiveSongName())==-1) return; + play(); +} + +void kmidClient::slotPause() +{ + if (m_kMid.pctl->playing==0) return; +#ifdef KMidDEBUG + printf("song Pause\n"); +#endif + if (m_kMid.pctl->paused==0) + { + if (m_kMid.pid!=0) + { + kill(m_kMid.pid,SIGTERM); + waitpid(m_kMid.pid, NULL, 0); + m_kMid.midi->closeDev(); + m_kMid.pid=0; + } + pausedatmillisec=(ulong)m_kMid.pctl->millisecsPlayed; + m_kMid.pctl->paused=1; + timer4timebar->stop(); + timer4events->stop(); + allNotesOff(); + // kill(m_kMid.pid,SIGSTOP); + // The previous line doesn't work because it stops the two processes (!?) + } + else + { + m_kMid.pctl->playing=0; + m_kMid.pctl->OK=0; + m_kMid.pctl->error=0; + m_kMid.pctl->gotomsec=pausedatmillisec; + m_kMid.pctl->message|=PLAYER_SETPOS; + + QApplication::flushX(); + if ((m_kMid.pid=fork())==0) + { +#ifdef KMidDEBUG + printf("PlayerProcessID: %d\n",getpid()); +#endif + player->play(0,(void (*)(void))kmidOutput); +#ifdef KMidDEBUG + printf("End of child process\n"); +#endif + _exit(0); + } + + while ((m_kMid.pctl->playing==0)&&(m_kMid.pctl->error==0)) ; + + if (m_kMid.pctl->error) return; + + m_kMid.pctl->OK=0; + m_kMid.pctl->paused=0; + + beginmillisec=m_kMid.pctl->beginmillisec-pausedatmillisec; + ulong currentmillisec=m_kMid.pctl->beginmillisec; + + int type; + ulong x=timeOfNextEvent(&type); + if (type!=0) + timer4events->start(x-(currentmillisec-beginmillisec),TRUE); + timer4timebar->start(1000); + + if (noteArray!=NULL) + { + int pgm[16]; + noteArray->moveIteratorTo(pausedatmillisec,pgm); + if (channelView!=NULL) + { + for (int j=0;j<16;j++) + { + if (!m_kMid.pctl->forcepgm[j]) channelView->changeInstrument(j,(m_kMid.pctl->gm==1)?(pgm[j]):(MT32toGM[pgm[j]])); + else channelView->changeInstrument(j,(m_kMid.pctl->pgm[j])); + } + } + + } + + } +} + +void kmidClient::shuttingDown(void) +{ + shuttingdown=true; + stop(); +} + +void kmidClient::slotStop() +{ + if (!m_kMid.pctl) return; + + if (!shuttingdown) + { + for (int i=0;i<16;i++) m_kMid.pctl->forcepgm[i]=FALSE; + if (channelView) channelView->reset(); + if (tempoLCD) + { + tempoLCD->display(tempoToMetronomeTempo(m_kMid.pctl->tempo)); + currentTempo=tempoLCD->getValue(); + tempoLCD->setDefaultValue(tempoToMetronomeTempo(m_kMid.pctl->tempo)*m_kMid.pctl->ratioTempo); + } + } + + if (m_kMid.pctl->playing==0) return; + + if (m_kMid.pctl->paused) return; +#ifdef KMidDEBUG + printf("song Stop\n"); +#endif + if (m_kMid.pid!=0) + { + kill(m_kMid.pid,SIGTERM); +#ifdef KMidDEBUG + printf("Killing\n"); +#endif + waitpid(m_kMid.pid, NULL, 0); + m_kMid.midi->closeDev(); + m_kMid.pid=0; + } + + m_kMid.pctl->playing=0; + ////////m_kMid.pctl->OK=0; + ////////m_kMid.pctl->message|=PLAYER_HALT; + timer4timebar->stop(); + timer4events->stop(); + + allNotesOff(); + + //m_kMid.pctl->playing=0; + //m_kMid.pctl->paused=0; + ////////while (m_kMid.pctl->OK==0) ; +} + +void kmidClient::slotRewind() +{ + if ((m_kMid.pctl->playing)&&(!m_kMid.pctl->paused)) + { + timebar->subtractPage(); + slotSeek(timebar->value()); + } +} + +void kmidClient::slotForward() +{ + if ((m_kMid.pctl->playing)&&(!m_kMid.pctl->paused)) + { + timebar->addPage(); + slotSeek(timebar->value()); + } +} + + +void kmidClient::allNotesOff() +{ + bool done=false; + m_kMid.pctl->isSendingAllNotesOff=true; + DeviceManager *_midi=new DeviceManager(); + _midi->initManager(); + _midi->openDev(); + _midi->allNotesOff(); + _midi->closeDev(); + delete _midi; + done=true; + m_kMid.pctl->isSendingAllNotesOff=false; +} + +void kmidClient::kmidOutput(void) +{ +// Should do nothing + /* + Midi_event *ev=pctl->ev; + + timeval tv; + gettimeofday(&tv, NULL); + ulong currentmillisec=tv.tv_sec*1000+tv.tv_usec/1000; + + if ((ev->command==MIDI_SYSTEM_PREFIX)&&((ev->command|ev->chn)==META_EVENT)) + { + if ((ev->d1==5)||(ev->d1==1)) + { + char *text=new char[ev->length+1]; + strncpy(text,(char *)ev->data,ev->length); + text[ev->length]=0; +#ifdef KMidDEBUG + printf("%s , played at: %ld\n",text,currentmillisec-beginmillisec); +#endif + } + else if (ev->d1==ME_SET_TEMPO) + { + int tempo=(ev->data[0]<<16)|(ev->data[1]<<8)|(ev->data[2]); + // printf("Change tempo: %d , %g, played at:%ld\n",tempo,tempoToMetronomeTempo(tempo),currentmillisec-beginmillisec); + } + + } + */ +} + + +void kmidClient::processSpecialEvent() +{ +/* + if (spev==NULL) + { + printf("SPEV == NULL !!!!!\n"); + return; + } +*/ + +//#ifdef KMidDEBUG +// printf(":::: %ld",passcount++); +// printf("%d %s %ld",spev->type,spev->text,spev->absmilliseconds); +//#endif + + int processNext=1; + int type; + ulong x; + + long delaymillisec=~0; + + while (processNext) + { + /* + timeval tv; + gettimeofday(&tv, NULL); + ulong currentmillisec=tv.tv_sec*1000+tv.tv_usec/1000; + */ + + x=timeOfNextEvent(&type); + + if (type==0) return; + if (type==1) + { + if ((spev->type==1) || (spev->type==5)) + { + kdispt->PaintIn(spev->type); + } + else if (spev->type==3) + { + tempoLCD->display(tempoToMetronomeTempo(spev->tempo)); +#ifdef KMidDEBUG + printf("Changing lcd tempo: spev->tempo: %d , ratio: %.9g\n",spev->tempo,m_kMid.pctl->ratioTempo); + printf("Result: %g %.9g %d\n",tempoToMetronomeTempo(spev->tempo),tempoToMetronomeTempo(spev->tempo),(int)tempoToMetronomeTempo(spev->tempo)); +#endif + currentTempo=tempoLCD->getValue(); + tempoLCD->setDefaultValue(tempoToMetronomeTempo(spev->tempo)*m_kMid.pctl->ratioTempo); + } + else if (spev->type==6) + { + rhythmview->setRhythm(spev->num,spev->den); + } + else if (spev->type==7) + { +#ifdef KMidDEBUG + printf("Beat: %d/%d\n",spev->num,spev->den); +#endif + rhythmview->Beat(spev->num); + } + m_kMid.pctl->SPEVprocessed++; + spev=spev->next; + } + if (type==2) + { + NoteArray::noteCmd *ncmd=noteArray->get(); + if (ncmd==NULL) {printf("ncmd is NULL !!!");return;} + if (channelView!=NULL) + { + if (ncmd->cmd==1) channelView->noteOn(ncmd->chn,ncmd->note); + else if (ncmd->cmd==0) channelView->noteOff(ncmd->chn,ncmd->note); + else if (ncmd->cmd==2) + if (!m_kMid.pctl->forcepgm[ncmd->chn]) channelView->changeInstrument(ncmd->chn,(m_kMid.pctl->gm==1)?(ncmd->note):(MT32toGM[ncmd->note])); + else channelView->changeInstrument(ncmd->chn,(m_kMid.pctl->pgm[ncmd->chn])); + + noteArray->next(); + } + } + processNext=0; + + x=timeOfNextEvent(&type); + + if (type==0) return; + + timeval tv; + ulong currentmillisec; + gettimeofday(&tv, NULL); + currentmillisec=tv.tv_sec*1000+tv.tv_usec/1000; + delaymillisec=x-(currentmillisec-beginmillisec); + if (delaymillisec<10) processNext=1; + } + + if (delaymillisec!=~(long)0) timer4events->start(delaymillisec,TRUE); + +} + +void kmidClient::repaintText(int type) +{ + kdispt->ChangeTypeOfTextEvents(type); + typeoftextevents=type; + kdispt->repaint(TRUE); +} + +int kmidClient::ChooseTypeOfTextEvents(void) +{ + return kdispt->ChooseTypeOfTextEvents(); +} + +void kmidClient::setSongType(int i) +{ + int autochangetype=0; + if ((m_kMid.pctl->playing==1)&&(m_kMid.pctl->paused==0)) autochangetype=1; + + if (autochangetype) + { + pause(); + } + m_kMid.pctl->gm=i; + + if (autochangetype) + { + pause(); + } + +} + + +QFont * kmidClient::getFont(void) +{ +return kdispt->getFont(); +} + +void kmidClient::fontChanged(void) +{ + kdispt->fontChanged(); +} + +void kmidClient::setMidiDevice(int i) +{ + midi->setDefaultDevice(i); +} + +void kmidClient::setMidiMapFilename(const char *mapfilename) +{ + MidiMapper *map=new MidiMapper(mapfilename); + if (map->ok()==-1) + { + QString tmp = locate("appdata", QString("maps/") + mapfilename); + delete map; + map=new MidiMapper(tmp.local8Bit()); + if (map->ok()!=1) + { + delete map; + map=new MidiMapper(NULL); + } + } + int autochangemap=0; + if ((m_kMid.pctl->playing==1)&&(m_kMid.pctl->paused==0)) autochangemap=1; + + if (autochangemap) + { + pause(); + } + midi->setMidiMap(map); + if (autochangemap) + { + pause(); + } +} + +void kmidClient::setSLManager(SLManager *slm) +{ + if (slman!=NULL) delete slman; + slman=slm; +} + +void kmidClient::setActiveCollection(int i) +{ + activecollection=i; + KConfig *kconf=KGlobal::instance()->config(); + + kconf->setGroup("KMid"); + kconf->writeEntry("ActiveCollection",activecollection); + currentsl=slman->getCollection(activecollection); + generateCPL(); + initializing_songs=1; + fillInComboSongs(); + initializing_songs=0; +} + +void kmidClient::fillInComboSongs(void) +{ + //int oldselected=comboSongs->currentItem(); + comboSongs->clear(); + //comboSongs->setCurrentItem(-1); + if (currentsl==NULL) return; + currentsl->iteratorStart(); + char temp[FILENAME_MAX]; + char temp2[FILENAME_MAX]; + QString qs; + while (!currentsl->iteratorAtEnd()) + { + qs=currentsl->getIteratorName(); + //KURL::decode(qs); + sprintf(temp,"%d - %s",currentsl->getIteratorID(), + extractFilename(KURL::decode_string(qs).ascii(),temp2)); + comboSongs->insertItem(temp); + currentsl->iteratorNext(); + } + if (currentsl->getActiveSongID()==-1) return; + comboSongs->setCurrentItem(currentsl->getActiveSongID()-1); + /* + if (oldselected==currentsl->getActiveSongID()-1) + { + slotSelectSong(currentsl->getActiveSongID()-1); + } + */ + slotSelectSong(currentsl->getActiveSongID()-1); +} + +void kmidClient::slotSelectSong(int i) +{ + if (currentsl==NULL) return; + i++; + if ((i<=0)) // The collection may be empty, or it may be just a bug :-) + { +#ifdef KMidDEBUG + printf("Empty\n"); +#endif + emit stopPause(); + if (m_kMid.pctl->playing) stop(); + if (midifile_opened!=NULL) delete midifile_opened; + midifile_opened=NULL; + player->removeSong(); + timebar->setRange(0,240000); + timebar->setValue(0); + timetags->repaint(TRUE); + kdispt->ClearEv(); + kdispt->repaint(TRUE); + comboSongs->clear(); + comboSongs->repaint(TRUE); + topLevelWidget()->setCaption("KMid"); + return; + } + + if ((i==currentsl->getActiveSongID())&&(!initializing_songs)) return; + int pl=0; + if (m_kMid.pctl->playing==1) pl=1; + + if (m_kMid.pctl->paused) emit stopPause(); + if (/*(i!=currentsl->getActiveSongID())&&*/(pl==1)) stop(); + currentsl->setActiveSong(i); + if (openURL(currentsl->getActiveSongName())==-1) return; + if (pl) play(); + +} + + +int kmidClient::getSelectedSong(void) +{ + if (currentsl==NULL) return -1; + return currentsl->getActiveSongID(); +} + + +void kmidClient::setSongLoop(int i) +{ + loopsong=i; +} + + +void kmidClient::generateCPL(void) +{ + delete [] collectionplaylist; + collectionplaylist=0; + + if (currentsl==NULL) return; + + if (collectionplaymode==0) + collectionplaylist=generate_list(currentsl->NumberOfSongs()); + else + collectionplaylist=generate_random_list(currentsl->NumberOfSongs()); +} + + +void kmidClient::setCollectionPlayMode(int i) +{ + collectionplaymode=i; + generateCPL(); +} + +void kmidClient::saveCollections(void) +{ + if (slman==NULL) return; +#ifdef KMidDEBUG + printf("Saving collections in: %s\n",collectionsfile.ascii()); +#endif + slman->saveConfig(QFile::encodeName(collectionsfile)); +} + +void kmidClient::saveLyrics(FILE *fh) +{ + if (kdispt!=NULL) kdispt->saveLyrics(fh); +} + +int kmidClient::searchInCPL(int song) +{ + if (currentsl==NULL) return -1; + int i=0; + int n=currentsl->NumberOfSongs(); + while ((i<n)&&(collectionplaylist[i]!=song)) i++; + if (i<n) return i; + return -1; +} + +void kmidClient::visibleVolumeBar(int i) +{ +#ifndef TEMPHACK + visiblevolumebar=i; + + if (visiblevolumebar) + volumebar->show(); + else + volumebar->hide(); +#endif +} + +void kmidClient::visibleChannelView(int i) +{ + if ((channelView==NULL)&&(i==1)) + { + channelView=new ChannelView(); + if (noteArray!=NULL) + { + int pgm[16],j; + noteArray->moveIteratorTo((ulong)m_kMid.pctl->millisecsPlayed,pgm); + for (j=0;j<16;j++) + { + if (!m_kMid.pctl->forcepgm[j]) channelView->changeInstrument(j,(m_kMid.pctl->gm==1)?(pgm[j]):(MT32toGM[pgm[j]])); + else channelView->changeInstrument(j,(m_kMid.pctl->pgm[j])); + channelView->changeForceState(j,m_kMid.pctl->forcepgm[j]); + } + } + channelView->show(); + connect(channelView,SIGNAL(signalToKMidClient(int *)),this,SLOT(communicationFromChannelView(int *))); + connect(kapp,SIGNAL(shutDown()),parentWidget(),SLOT(shuttingDown())); + + } + else if ((channelView!=NULL)&&(i==0)) + { + delete channelView; + channelView=NULL; + + } + rethinkNextEvent(); +} + +void kmidClient::channelViewDestroyed() +{ + channelView=NULL; + rethinkNextEvent(); +} + + +void kmidClient::rethinkNextEvent(void) +{ + if (m_kMid.pctl->playing==0) return; + timer4events->stop(); + + int type; + ulong delaymillisec; + ulong x=timeOfNextEvent(&type); + + if (type==0) return; + + timeval tv; + ulong currentmillisec; + gettimeofday(&tv, NULL); + currentmillisec=tv.tv_sec*1000+tv.tv_usec/1000; + delaymillisec=x-(currentmillisec-beginmillisec); + + timer4events->start(delaymillisec,TRUE); +} + +void kmidClient::communicationFromChannelView(int *i) +{ + if (i==NULL) return; + int autocontplaying=0; + if ((i[0]==CHN_CHANGE_PGM)||((i[0]==CHN_CHANGE_FORCED_STATE)&&(i[3]==1))) + { + if ((m_kMid.pctl->playing==1)&&(m_kMid.pctl->paused==0)) autocontplaying=1; + + if (autocontplaying) + { + pause(); + } + } + if (i[0]==CHN_CHANGE_PGM) + m_kMid.pctl->pgm[i[1]-1]=i[2]; + else if (i[0]==CHN_CHANGE_FORCED_STATE) + m_kMid.pctl->forcepgm[i[1]-1]=i[2]; + if ((i[0]==CHN_CHANGE_PGM)||((i[0]==CHN_CHANGE_FORCED_STATE)&&(i[3]==1))) + { + if (autocontplaying) + { + pause(); + } + } + +} + +void kmidClient::slotSetTempo(double value) +{ + if (!player->isSongLoaded()) + { + tempoLCD->display(120); + currentTempo=120; + tempoLCD->setDefaultValue(120); + return; + } + +#ifdef KMidDEBUG + printf("Change tempo to %g\n",value); +#endif + int autocontplaying=0; + + if ((m_kMid.pctl->playing==1)&&(m_kMid.pctl->paused==0)) autocontplaying=1; + + + if (autocontplaying) + { + pause(); + } + +// double ratio=(tempoToMetronomeTempo(m_kMid.pctl->tempo)*m_kMid.pctl->ratioTempo)/(value); +// double ratio=(tempoLCD->getOldValue()*m_kMid.pctl->ratioTempo)/(value); + double ratio=(currentTempo*m_kMid.pctl->ratioTempo)/value; + + char s[20]; + sprintf(s,"%g",ratio); + if (strcmp(s,"1")!=0) tempoLCD->setLCDColor (255,100,100); + else tempoLCD->setLCDColor (100,255,100); +#ifdef KMidDEBUG + printf("ratio: (%.9g = %g ) tempo now: %g , new tempo %g\n",ratio,ratio,tempoToMetronomeTempo(m_kMid.pctl->tempo),value); + printf("OldValue: %g , value %g\n",tempoLCD->getOldValue(),value); +#endif + + if (m_kMid.pctl->paused==1) + { + pausedatmillisec=(long)(((double)pausedatmillisec/m_kMid.pctl->ratioTempo)*ratio); +#ifdef KMidDEBUG + printf("pausedat: %ld\n",pausedatmillisec); +#endif + } + player->setTempoRatio(ratio); + + timebar->setRange(0,(int)(player->information()->millisecsTotal)); + timebar->setValue(pausedatmillisec); + timetags->repaint(TRUE); + + kdispt->ClearEv(false); + + noteArray=player->noteArray(); + spev=player->specialEvents(); + currentTempo=value; + + while (spev!=NULL) + { + if ((spev->type==1) || (spev->type==5)) + { + kdispt->AddEv(spev); + } + spev=spev->next; + } + + kdispt->calculatePositions(); + kdispt->CursorToHome(); + if (m_kMid.pctl->paused==1) + moveEventPointersTo(pausedatmillisec); + + if (autocontplaying) + { + pause(); + } + +} + +void kmidClient::downloadFinished(KIO::Job *) +{ + downloaded=true; + kapp->exit_loop(); +} + +QSize kmidClient::sizeHint() const +{ + QSize sh = QWidget::sizeHint(); + return sh.expandedTo(QSize(560,420)); +} + +QSizePolicy kmidClient::sizePolicy() +{ + return QSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); +} + + +void kmidClient::play() +{ + slotPlay(); +} +void kmidClient::pause() +{ + slotPause(); +} +void kmidClient::stop() +{ + slotStop(); +} +void kmidClient::rewind() +{ + slotRewind(); +} +void kmidClient::forward() +{ + slotForward(); +} +void kmidClient::seek(int ms) +{ + slotSeek(ms); +} +void kmidClient::prevSong() +{ + slotPrevSong(); +} +void kmidClient::nextSong() +{ + slotNextSong(); +} +void kmidClient::setVolume(int i) +{ + slotSetVolume(200-i); +} +void kmidClient::setTempo(int i) +{ + slotSetTempo(i); +} +void kmidClient::setSongEncoding( int i ) +{ + KListAction *tmplistaction= + ((KListAction*)actionCollection->action("file_type")); + + tmplistaction->setCurrentItem(i); +} +void kmidClient::setLyricEvents( int i ) +{ + KListAction *tmplistaction= + ((KListAction*)actionCollection->action("display_events")); + tmplistaction->setCurrentItem(i); +} +void kmidClient::setCurrentSong(int i) +{ + getComboSongs()->setCurrentItem(i-1); + slotSelectSong(i-1); +} +void kmidClient::setPlayListMode(int i) +{ + ((KListAction*)actionCollection->action("play_order"))->setCurrentItem(i); +} +void kmidClient::slotSelectEncoding(int i) +{ + if (i == 0) + kdispt->setLyricsEncoding(QString::null); // Default + else + kdispt->setLyricsEncoding(KGlobal::charsets()->encodingForName(comboEncodings->text(i))); +} +#include "kmidclient.moc" diff --git a/kmid/kmidclient.h b/kmid/kmidclient.h new file mode 100644 index 00000000..18d33d66 --- /dev/null +++ b/kmid/kmidclient.h @@ -0,0 +1,240 @@ +/************************************************************************** + + kmidclient.h - The main client widget of KMid + Copyright (C) 1997,98 Antonio Larrosa Jimenez + + 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. + + Send comments and bug fixes to larrosa@kde.org + or to Antonio Larrosa, Rio Arnoya, 10 5B, 29006 Malaga, Spain + +***************************************************************************/ +#ifndef _KMIDCLIENT_H +#define _KMIDCLIENT_H + +#include "qslidertime.h" +#include <libkmid/player.h> +#include <libkmid/track.h> +#include <libkmid/notearray.h> +#include <libkmid/libkmid.h> +#include <qtimer.h> +#include <unistd.h> +#include <sys/time.h> +#include <sys/types.h> +#include "kdisptext.h" +#include "slman.h" +#include "version.h" +#include "kmidIface.h" + +#include <kio/job.h> + +class DeviceManager; + + +class KApplication; +class KConfig; +class KLCDNumber; +class QLabel; +class QComboBox; +class RhythmView; +class ChannelView; +class QString; + +class kmidClient : public QWidget, virtual public KMidIface +{ + Q_OBJECT +private: +#ifdef KMidDEBUG + long passcount; +#endif + + DeviceManager *midi; + MidiPlayer *player; + + struct kMidData m_kMid; + + QTimer *timer4timebar; + QTimer *timer4events; + + ulong beginmillisec; + ulong pausedatmillisec; + double currentTempo; + SpecialEvent *spev; + NoteArray *noteArray; + + bool downloaded; + + int itsme; + bool shuttingdown; + int visiblevolumebar; + + char *midifile_opened; + int hasbeenopened; + + int typeoftextevents; + + SLManager *slman; + int activecollection; + QString collectionsfile; + SongList *currentsl; + int initializing_songs; + int loopsong; + int collectionplaymode; + int *collectionplaylist; // the list of songs ordered in the + // user selected mode + + class KActionCollection *actionCollection; + + void generateCPL(void); + int searchInCPL(int song); // Returns the index of song + + void fillInComboSongs(void); + + int openFile(const char *filename); + void allNotesOff(void); +public: + kmidClient(QWidget *parent, KActionCollection *ac, const char *name=0); + ~kmidClient(); + + char *midiFileName(void) {return midifile_opened;}; + // If it returns NULL then there isn't any file opened + + int isPlaying(void) {return m_kMid.pctl->playing;}; + int isPaused(void) {return (m_kMid.pctl->playing)&&(m_kMid.pctl->paused);}; + + int openURL(const QString s); + + void repaintText(int typeoftextevents); + static void kmidOutput(void); + + int ChooseTypeOfTextEvents(void); + + QFont *getFont(void); + void fontChanged(void); // The new font is already in KConfig + + SLManager *getSLManager(void) {return slman;}; + void setSLManager(SLManager *slm); + // setSLManager only change the pointer, so DO NOT DELETE + // the objectr you pass to it + int getActiveCollection(void) {return activecollection;}; + void setActiveCollection(int i); + int getSelectedSong(void); + void saveCollections(void); + + void setSongType(int i); + void setSongLoop(int i); + void setCollectionPlayMode(int i); + + void visibleVolumeBar(int i); // 1 shows it, and 0 hides it + // int isVisibleVolumeBar(void) {return visiblevolumebar;}; + void visibleChannelView(int i); + + void shuttingDown(void); + + ulong timeOfNextEvent(int *type=NULL); + void rethinkNextEvent(void); + // Recalculates time of next event and updates the timer4events according to it + + + void moveEventPointersTo(ulong ms); + +protected: +// void resizeEvent(QResizeEvent *qre); + + +public slots: +// void help_Help(); +// void help_About(); + void slotPlay(); + void slotPause(); + void slotStop(); + void slotRewind(); + void slotForward(); + void slotPrevSong(); + void slotNextSong(); + + void timebarUpdate(); + void slotSeek(int i); + void slotSetVolume(int i); + void slotSelectSong(int i); + void slotSelectEncoding(int i); + + void downloadFinished( KIO::Job * ); + + void processSpecialEvent(); + + void channelViewDestroyed(); + + void communicationFromChannelView(int *); + + void slotSetTempo(double value); + +signals: + void mustRechooseTextEvent(); + void stopPause(); +// void channelView_Destroyed(); + +public: + void saveLyrics(FILE *fh); + + DeviceManager *devman(void) {return midi;}; + void setMidiDevice(int i); + void setMidiMapFilename(const char *mapfilename); + + ChannelView *getChannelView(void) { return channelView; }; + KDisplayText *getKDisplayText(void) { return kdispt; }; + + QSizePolicy sizePolicy(); + + QComboBox *getComboSongs() { return comboSongs; }; + + + void play(); + void pause(); + void stop(); + void rewind(); + void forward(); + void seek(int ms); + void prevSong(); + void nextSong(); + void setVolume(int i); + void setTempo(int i); + void setSongEncoding( int i ); + void setLyricEvents( int i ); + void setCurrentSong(int i); + void setPlayListMode(int i); + + QSize sizeHint() const; +private: + QSlider *timebar; + QSliderTime *timetags; + QSlider *volumebar; + + KLCDNumber *tempoLCD; + KDisplayText *kdispt; + QLabel *qlabelTempo; + QComboBox *comboSongs; + QComboBox *comboEncodings; + RhythmView *rhythmview; + + + ChannelView *channelView; + +}; + +char *extractFilename(const char *in,char *out); // returns a pointer to out + +#endif + diff --git a/kmid/kmidframe.cpp b/kmid/kmidframe.cpp new file mode 100644 index 00000000..007f0b82 --- /dev/null +++ b/kmid/kmidframe.cpp @@ -0,0 +1,728 @@ +/************************************************************************** + + kmidframe.cpp - The main widget of KMid + Copyright (C) 1997,98 Antonio Larrosa Jimenez + + 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 + + Send comments and bug fixes to larrosa@kde.org + or to Antonio Larrosa, Rio Arnoya, 10 5B, 29006 Malaga, Spain + +***************************************************************************/ + +#include <stdio.h> +#include <unistd.h> +#include <sys/shm.h> +#include <sys/wait.h> +#include <sys/stat.h> + +#include <qkeycode.h> +#include <qstring.h> + +#include <kaccel.h> +#include <kapplication.h> +#include <kconfig.h> +#include <kcmdlineargs.h> +#include <kfiledialog.h> +#include <kfontdialog.h> +#include <kglobal.h> +#include <kiconloader.h> +#include <klocale.h> +#include <kmessagebox.h> +#include <ktoolbar.h> +#include <kurl.h> +#include <kdebug.h> +#include <kaction.h> +#include <kstdaction.h> +#include <kurldrag.h> +#include <kedittoolbar.h> +#include <dcopclient.h> + +#include "kmidframe.h" +#include "kmidclient.h" +#include "midicfgdlg.h" +#include "collectdlg.h" +#include "channelcfgdlg.h" +#include "channelview.h" +#include "version.h" + +kmidFrame::kmidFrame(const char *name) + :KMainWindow(0, name) +{ + kmidclient=new kmidClient(this,actionCollection(), "KMidClient"); + kmidclient->setSongType(1); + kmidclient->show(); + setCentralWidget( kmidclient ); +/* + kKeysAccel=new KAccel(this); + kKeysAccel->insertItem(i18n("Play/Pause"),"Play/Pause", Key_Space); + kKeysAccel->connectItem("Play/Pause", this, SLOT(spacePressed())); + kKeysAccel->insertItem(i18n("Stop"),"Stop", Key_Backspace); + kKeysAccel->connectItem("Stop",kmidclient,SLOT(song_Stop())); + kKeysAccel->insertItem(i18n("Previous Song"),"Previous Song", Key_Left); + kKeysAccel->connectItem("Previous Song",kmidclient,SLOT(song_PlayPrevSong())); + kKeysAccel->insertItem(i18n("Next Song"),"Next Song", Key_Right); + kKeysAccel->connectItem("Next Song",kmidclient,SLOT(song_PlayNextSong())); + kKeysAccel->insertItem(i18n("Scroll Down Karaoke"),"Scroll down karaoke",Key_Down); + kKeysAccel->connectItem("Scroll Down karaoke",kmidclient->getKDisplayText(),SLOT(ScrollDown())); + kKeysAccel->insertItem(i18n("Scroll Up Karaoke"),"Scroll up karaoke",Key_Up); + kKeysAccel->connectItem("Scroll Up Karaoke",kmidclient->getKDisplayText(),SLOT(ScrollUp())); + kKeysAccel->insertItem(i18n("Scroll Page Down Karaoke"),"Scroll page down karaoke",Key_PageDown); + kKeysAccel->connectItem("Scroll Page Down Karaoke",kmidclient->getKDisplayText(),SLOT(ScrollPageDown())); + kKeysAccel->insertItem(i18n("Scroll Page Up Karaoke"),"Scroll page up karaoke",Key_PageUp); + kKeysAccel->connectItem("Scroll Page Up Karaoke",kmidclient->getKDisplayText(),SLOT(ScrollPageUp())); + + kKeysAccel->readSettings(); +*/ + KStdAction::open(this, SLOT(file_Open()), actionCollection()); + (void)new KAction(i18n("&Save Lyrics..."), 0, this, + SLOT(file_SaveLyrics()), actionCollection(), "file_save_lyrics"); + KStdAction::quit(kapp, SLOT(quit()), actionCollection()); + + (void)new KAction(i18n("&Play"), "player_play", Qt::Key_Space, + kmidclient, SLOT(slotPlay()), actionCollection(), "song_play"); + (void)new KAction(i18n("P&ause"), "player_pause", Qt::Key_P, kmidclient, + SLOT(slotPause()), actionCollection(), "song_pause"); + (void)new KAction(i18n("&Stop"), "player_stop", Qt::Key_Backspace, + kmidclient, SLOT(slotStop()), actionCollection(), "song_stop"); + + (void)new KAction(i18n("P&revious Song"), "player_start", Key_Left, + kmidclient, SLOT(slotPrevSong()), actionCollection(), + "song_previous"); + (void)new KAction(i18n("&Next Song"), "player_end", Key_Right, + kmidclient, SLOT(slotNextSong()), actionCollection(), + "song_next"); + (void)new KToggleAction(i18n("&Loop"), 0, this, SLOT(song_Loop()), + actionCollection(), "song_loop"); + + (void)new KAction(i18n("Rewind"), "2leftarrow", 0, kmidclient, + SLOT(slotRewind()), actionCollection(), "song_rewind"); + + (void)new KAction(i18n("Forward"), "2rightarrow", 0, kmidclient, + SLOT(slotForward()), actionCollection(), "song_forward"); + + (void)new KAction(i18n("&Organize..."), 0, this, SLOT(collect_organize()), + actionCollection(), "collect_organize"); + + QStringList playmodes; + playmodes.append(i18n("In Order")); + playmodes.append(i18n("Shuffle")); + + KSelectAction *act=new KSelectAction(i18n("Play Order"), 0, /*this, SLOT(collect_PlayOrder(int)),*/ + actionCollection(), "play_order"); + connect(act,SIGNAL(activated(int)),this, SLOT(collect_PlayOrder(int))); + act->setItems(playmodes); + + (void)new KToggleAction(i18n("Auto-Add to Collection"), 0, this, + SLOT(collect_AutoAdd()), actionCollection(), "collect_autoadd"); + + playmodes.clear(); + playmodes.append(i18n("&General MIDI")); + playmodes.append(i18n("&MT-32")); + + act=new KSelectAction(i18n("File Type"), 0,/* this, SLOT(options_FileType(int)),*/ + actionCollection(), "file_type"); + connect(act,SIGNAL(activated(int)),this, SLOT(options_FileType(int))); + act->setItems(playmodes); + + playmodes.clear(); + playmodes.append(i18n("&Text Events")); + playmodes.append(i18n("&Lyric Events")); + + act=new KSelectAction(i18n("Display Events"), Key_T, /*this, + SLOT(options_DisplayEvents(int)),*/ actionCollection(), + "display_events"); + connect(act,SIGNAL(activated(int)),this, SLOT(options_DisplayEvents(int))); + act->setItems(playmodes); + + (void)new KToggleAction(i18n("Automatic Text Chooser"), 0, this, + SLOT(options_AutomaticText()), actionCollection(), + "option_automatictext"); + + KToggleAction* togact = new KToggleAction(i18n("Show &Volume Bar"), "volume", + 0, this, SLOT(options_ShowVolumeBar()), actionCollection(), + "toggle_volumebar"); + togact->setCheckedState(i18n("Hide &Volume Bar")); + + togact = new KToggleAction(i18n("Show &Channel View"), "piano", + 0, this, SLOT(options_ShowChannelView()), actionCollection(), + "toggle_channelview"); + togact->setCheckedState(i18n("Hide &Channel View")); + + (void)new KAction(i18n("Channel View &Options..."), 0, this, + SLOT(options_ChannelViewOptions()), actionCollection(), + "channelview_options"); + + (void)new KAction(i18n("&Font Change..."), 0, this, + SLOT(options_FontChange()), actionCollection(), + "change_font"); + + (void)new KAction(i18n("MIDI &Setup..."), 0, this, + SLOT(options_MidiSetup()), actionCollection(), "midi_setup"); + + + setupGUI((ToolBar | Keys | StatusBar | Save | Create ), "kmidui.rc" ); + + KConfig *cfg=kapp->config(); + cfg->setGroup("KMid"); + KSelectAction *tmplistaction= + ((KSelectAction*)actionCollection()->action("display_events")); + + if (cfg->readNumEntry("TypeOfTextEvents",5)==5) + tmplistaction->setCurrentItem(1); + else + tmplistaction->setCurrentItem(0); + + tmplistaction=((KSelectAction*)actionCollection()->action("file_type")); + if (cfg->readNumEntry("TypeOfMidiFile",0)==0) + tmplistaction->setCurrentItem(0); + else + tmplistaction->setCurrentItem(1); + + if (cfg->readNumEntry("Loop",0)==1) + ((KToggleAction*)actionCollection()->action("song_loop"))->setChecked(true); + + if (cfg->readNumEntry("ShowVolumeBar",0)==1) + ((KToggleAction*)actionCollection()->action("toggle_volumebar"))->setChecked(true); + + + tmplistaction=((KSelectAction*)actionCollection()->action("play_order")); + if (cfg->readNumEntry("CollectionPlayMode",0)==0) + tmplistaction->setCurrentItem(0); + else + tmplistaction->setCurrentItem(1); + + if ((cfg->readNumEntry("AutoAddToCollection",0))==1) + ((KToggleAction*)actionCollection()->action("collect_autoadd"))->setChecked(true); + + if ((cfg->readNumEntry("AutomaticTextEventChooser",1))==1) + ((KToggleAction*)actionCollection()->action("option_automatictext"))->setChecked(true); + + setAcceptDrops(true); + + connect( kmidclient, SIGNAL( mustRechooseTextEvent() ), + this, SLOT( rechooseTextEvent() ) ); + + connect( kmidclient, SIGNAL( stopPause() ), + this, SLOT( song_stopPause() ) ); + +// connect( kmidclient, SIGNAL( channelView_Destroyed() ), +// this, SLOT( channelViewDestroyed() ) ); + + KCmdLineArgs * args = KCmdLineArgs::parsedArgs(); + + if ( args->count() > 0 ) + { +// printf("Opening command line file...\n"); + int backautoadd=cfg->readNumEntry("AutoAddToCollection",0); + cfg->writeEntry("AutoAddToCollection",0); + + char ttt[40]; + sprintf(ttt,"%d",kapp->argc()); + int i=0; + int c=autoAddSongToCollection( args->url( 0 ).path() , 1 ); + i++; + while (i<args->count()) + { + autoAddSongToCollection( args->url( i ).path() , 0 ); + i++; + } + + kmidclient->setActiveCollection(c); + + /// kmidclient->openURL((kapp->argv())[1]); + /* if ((cfg->readNumEntry("AutomaticTextEventChooser",1))==1) + { + if (kmidclient->ChooseTypeOfTextEvents()==1) + options_Text(); + else + options_Lyrics(); + }*/ + if (kmidclient->midiFileName()!=NULL) kmidclient->play(); + cfg->writeEntry("AutoAddToCollection",backautoadd); + } + + args->clear(); + /* + kKeys->addKey("Play/Pause",Key_Space); + kKeys->registerWidget("KMidFrame",this); + kKeys->connectFunction("KMidFrame","Play/Pause",this,SLOT(spacePressed())); + */ +// kKeysAccel->writeSettings(cfg); + + DCOPClient *client = kapp->dcopClient(); + if (!client->isRegistered()) // just in case we're embeeded + { + client->attach(); + client->registerAs("kmid"); + } +} + +kmidFrame::~kmidFrame() +{ +} + +void kmidFrame::file_Open() +{ + KURL url = KFileDialog::getOpenURL(QString::null, "*.kar *.mid *.kar.gz *.mid.gz\n*.kar *.kar.gz\n*.mid *.mid.gz\n*",this); + + if( url.isEmpty() ) + return; + + if( !url.isLocalFile() ) + { + KMessageBox::sorry( 0L, i18n( "Only local files are currently supported." ) ); + return; + } + + openURL(url.path()); +} + + + +void kmidFrame::song_stopPause() +{ + if (kmidclient->isPaused()) + { + // song_Pause(); + ((KToggleAction*)actionCollection()->action("song_pause"))->setChecked(false); + kmidclient->pause(); + } +} + +void kmidFrame::options_FileType(int i) +{ + KConfig *cfg=kapp->config(); + cfg->setGroup("KMid"); + cfg->writeEntry("TypeOfMidiFile",i); + kmidclient->setSongType(1-i); +} + +void kmidFrame::options_DisplayEvents(int i) +{ + KConfig *cfg=kapp->config(); + cfg->setGroup("KMid"); + cfg->writeEntry("TypeOfTextEvents",(i==0)?1:5); + cfg->sync(); + kmidclient->repaintText((i==0)?1:5); +} + +void kmidFrame::options_AutomaticText() +{ + KConfig *cfg=kapp->config(); + cfg->setGroup("KMid"); + cfg->writeEntry("AutomaticTextEventChooser",1-cfg->readNumEntry("AutomaticTextEventChooser",1)); +} + +void kmidFrame::options_FontChange() +{ + KFontDialog *kfd=new KFontDialog(this); + QFont font; + font=*kmidclient->getFont(); + kfd->getFont(font); + delete kfd; + KConfig *cfg=kapp->config(); + cfg->setGroup("KMid"); + cfg->writeEntry("KaraokeFont",font); + cfg->sync(); + kmidclient->fontChanged(); +} + +int kmidFrame::autoAddSongToCollection(const QString& filename,int setactive) +{ + int r; + SLManager *slman; + SongList *sl; + KConfig *cfg=kapp->config(); + cfg->setGroup("KMid"); + if (cfg->readNumEntry("AutoAddToCollection",0)==0) + { + r=0; + slman=kmidclient->getSLManager(); + if (setactive) slman->createTemporaryCollection(); + sl=slman->getCollection(0); + if (filename==NULL) sl->AddSong(kmidclient->midiFileName()); + else sl->AddSong(QFile::encodeName(filename)); + } + else + { + slman=kmidclient->getSLManager(); + sl=slman->getCollection(kmidclient->getActiveCollection()); + r=kmidclient->getActiveCollection(); + if (sl==NULL) return 0; + int id; + if (filename==NULL) id=sl->AddSong(kmidclient->midiFileName()); + else id=sl->AddSong(QFile::encodeName(filename)); + if (setactive) + { + sl->setActiveSong(id); + } + } + return r; +} + +void kmidFrame::urlDrop_slot(QDropEvent* e) +{ + dropEvent(e); +} + +void kmidFrame::dragEnterEvent(QDragEnterEvent* e) +{ + e->accept(KURLDrag::canDecode(e)); +} + +void kmidFrame::dropEvent( QDropEvent * event ) +{ + KURL::List list; + KURLDrag::decode(event, list); + + if (list.count()==0) return; + + bool first = true; + int c = true; + + for (KURL::List::ConstIterator it = list.begin(); + it != list.end(); ++it) + { + if (!(*it).isLocalFile()) + continue; + + if (first) + { + c = autoAddSongToCollection((*it).path(),1); + first = false; + } + else + { + autoAddSongToCollection((*it).path(),0); + } + } + + if (!first) + { + kmidclient->setActiveCollection(c); + + if ((!kmidclient->isPlaying())&&(kmidclient->midiFileName()!=NULL)) + kmidclient->play(); + } +} + +void kmidFrame::shuttingDown() +{ + if (kmidclient->isPlaying()==1) + { +// kmidclient->stop(); + kmidclient->shuttingDown(); + } + kmidclient->saveCollections(); +} + +void kmidFrame::saveProperties(KConfig *cfg) +{ + kmidclient->saveCollections(); + int play=kmidclient->isPlaying(); + cfg->writeEntry("File",kmidclient->midiFileName()); + cfg->writeEntry("ActiveCollection",kmidclient->getActiveCollection()); + cfg->writeEntry("ActiveSong",kmidclient->getSelectedSong()); + cfg->writeEntry("Playing",play); +} + +void kmidFrame::readProperties(KConfig *cfg) +{ + int activecol=cfg->readNumEntry("ActiveCollection",0); + int activesong=cfg->readNumEntry("ActiveSong",0); + int wasplaying=cfg->readNumEntry("Playing",0); + SLManager *slman=kmidclient->getSLManager(); + SongList *sl=slman->getCollection(activecol); + sl->setActiveSong(activesong); + kmidclient->setActiveCollection(activecol); + kmidclient->slotSelectSong(activesong-1); + + if ((activecol==0)&&(wasplaying)) // It was the temporary collection, + { // surely the user would like to continue + // hearing the song + QString s = cfg->readPathEntry("File"); + int c=autoAddSongToCollection(s,1); + kmidclient->setActiveCollection(c); + } + + if ((wasplaying)&&(kmidclient->midiFileName()!=NULL)) kmidclient->play(); +} + +void kmidFrame::options_MidiSetup() +{ + if (kmidclient->devman()->checkInit()<0) + { + KMessageBox::error(this, + i18n("Could not open /dev/sequencer to get some info.\nProbably there is another program using it.")); + return; + } + MidiConfigDialog *dlg; + + dlg=new MidiConfigDialog(kmidclient->devman(),NULL,"MidiDialog"); + if (dlg->exec() == QDialog::Accepted) + { + KConfig *cfg=kapp->config(); + cfg->setGroup("KMid"); + cfg->writeEntry("MidiPortNumber",MidiConfigDialog::selecteddevice); + kmidclient->setMidiDevice(MidiConfigDialog::selecteddevice); + cfg->setGroup("Midimapper"); + cfg->writePathEntry("LoadFile", + (MidiConfigDialog::selectedmap==NULL)? QString::null:MidiConfigDialog::selectedmap); + kmidclient->setMidiMapFilename(MidiConfigDialog::selectedmap); + } + delete dlg; +} + +void kmidFrame::collect_organize() +{ + CollectionDialog *dlg; + SLManager *slman=new SLManager(*kmidclient->getSLManager()); + int idx=kmidclient->getActiveCollection(); + + dlg=new CollectionDialog(slman,idx,NULL,"MidiDialog"); + if (dlg->exec() == QDialog::Accepted) + { + kmidclient->setSLManager(slman); + kmidclient->setActiveCollection(CollectionDialog::selectedC); + kmidclient->slotSelectSong( + (slman->getCollection(CollectionDialog::selectedC))->getActiveSongID()-1); + } + else + { + delete slman; + } +delete dlg; +} + +void kmidFrame::rechooseTextEvent() +{ + KConfig *cfg=kapp->config(); + cfg->setGroup("KMid"); + if ((cfg->readNumEntry("AutomaticTextEventChooser",1))==1) + { + int t=kmidclient->ChooseTypeOfTextEvents(); + kmidclient->repaintText(t); + if (t==1) + ((KSelectAction*)actionCollection()->action("display_events"))->setCurrentItem(0); + else + ((KSelectAction*)actionCollection()->action("display_events"))->setCurrentItem(1); + } +} + +void kmidFrame::song_Loop() +{ + KConfig *cfg=kapp->config(); + cfg->setGroup("KMid"); + int i=1-cfg->readNumEntry("Loop",0); + cfg->writeEntry("Loop",i); + cfg->sync(); + kmidclient->setSongLoop(i); +} + +void kmidFrame::collect_PlayOrder(int i) +{ + KConfig *cfg=kapp->config(); + cfg->setGroup("KMid"); + cfg->writeEntry("CollectionPlayMode", i); + cfg->sync(); + kmidclient->setCollectionPlayMode(i); +} + +void kmidFrame::collect_AutoAdd() +{ + KConfig *cfg=kapp->config(); + cfg->setGroup("KMid"); + cfg->writeEntry("AutoAddToCollection",1-cfg->readNumEntry("AutoAddToCollection",0)); + cfg->sync(); +} + +void kmidFrame::file_SaveLyrics() +{ + KURL url = KFileDialog::getSaveURL(QString::null,"*",this); + + if( url.isEmpty() ) + return; + + if( !url.isLocalFile() ) + { + KMessageBox::sorry( 0L, i18n( "Only local files are currently supported." ) ); + return; + } + + QString filename = url.path(); + struct stat statbuf; + + if (stat(QFile::encodeName(filename), &statbuf)!=-1) + { + QString s = i18n("File %1 already exists\nDo you want to overwrite it?").arg(filename); + if (KMessageBox::warningYesNo(this,s,QString::null,i18n("Overwrite"),KStdGuiItem::cancel())==1) + return; + } + + FILE *fh=fopen(QFile::encodeName(filename),"wt"); + kmidclient->saveLyrics(fh); + fclose(fh); +} + +void kmidFrame::spacePressed() +{ + if (!kmidclient->isPlaying()) kmidclient->play(); + else pause(); +} +void kmidFrame::options_ShowVolumeBar() +{ + KConfig *cfg=kapp->config(); + cfg->setGroup("KMid"); + int i=1-cfg->readNumEntry("ShowVolumeBar",0); + cfg->writeEntry("ShowVolumeBar",i); + kmidclient->visibleVolumeBar(i); +} + +void kmidFrame::options_ShowChannelView() +{ + if (!((KToggleAction*)actionCollection()->action("toggle_channelview"))->isChecked()) + { + kmidclient->visibleChannelView(0); + } else + { + kmidclient->visibleChannelView(1); + connect (kmidclient->getChannelView(),SIGNAL(destroyMe()),this,SLOT(channelViewDestroyed())); + } + +} + +void kmidFrame::channelViewDestroyed() +{ + kmidclient->channelViewDestroyed(); + ((KToggleAction*)actionCollection()->action("toggle_channelview"))->setChecked(false); +} + +void kmidFrame::options_ChannelViewOptions() +{ + ChannelViewConfigDialog *dlg; + + dlg=new ChannelViewConfigDialog(NULL,"ChannelViewConfigDialog"); + if (dlg->exec() == QDialog::Accepted) + { + if (kmidclient->getChannelView()) + kmidclient->getChannelView()->lookMode( + ChannelViewConfigDialog::selectedmode ); + } + delete dlg; +} + +void kmidFrame::openURL( const QString url ) +{ + int c=autoAddSongToCollection(url,1); + kmidclient->setActiveCollection(c); +} + +/*void kmidFrame::play() +{ + kmidclient->play(); +} + +void kmidFrame::pause() +{ +// kmidclient->pause(); + ((KAction*)actionCollection()->action("pause"))->activate(); +} + +void kmidFrame::stop() +{ + kmidclient->stop(); +} + +void kmidFrame::rewind() +{ + kmidclient->rewind(); +} + +void kmidFrame::forward() +{ + kmidclient->forward(); +} + +void kmidFrame::seek(int ms) +{ + kmidclient->timebarChange(ms); +} + +void kmidFrame::prevSong() +{ + kmidclient->prevSong(); +} + +void kmidFrame::nextSong() +{ + kmidclient->nextSong(); +} + +void kmidFrame::setSongLoop(int i) +{ + ((KToggleAction*)actionCollection()->action("song_loop"))->setChecked(i!=0); +} + +void kmidFrame::setVolume(int i) +{ + kmidclient->volumebarChange(200-i); +} + +void kmidFrame::setTempo(int i) +{ + kmidclient->changeTempo(i); +} + +void kmidFrame::setSongType( int i ) +{ + KSelectAction *tmplistaction= + ((KSelectAction*)actionCollection()->action("file_type")); + + tmplistaction->setCurrentItem(i); +} + +void kmidFrame::setLyricEvents( int i ) +{ + KSelectAction *tmplistaction= + ((KSelectAction*)actionCollection()->action("display_events")); + tmplistaction->setCurrentItem(i); +} + +void kmidFrame::selectSong(int i) +{ + kmidclient->getComboSongs()->setCurrentItem(i-1); + kmidclient->selectSong(i-1); +} + +void kmidFrame::setActiveCollection( int i ) +{ + kmidclient->setActiveCollection(i); +} + +void kmidFrame::setCollectionPlayMode(int i) +{ + ((KSelectAction*)actionCollection()->action("play_order"))->setCurrentItem(i); +} + +void kmidFrame::setMidiDevice(int i) +{ + + +} +*/ + + +#include "kmidframe.moc" diff --git a/kmid/kmidframe.h b/kmid/kmidframe.h new file mode 100644 index 00000000..e88c902a --- /dev/null +++ b/kmid/kmidframe.h @@ -0,0 +1,133 @@ +/************************************************************************** + + kmidframe.h - The main widget of KMid + Copyright (C) 1997,98 Antonio Larrosa Jimenez + + 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. + + Send comments and bug fixes to larrosa@kde.org + or to Antonio Larrosa, Rio Arnoya, 10 5B, 29006 Malaga, Spain + +***************************************************************************/ +#ifndef _KMIDFRAME_H +#define _KMIDFRAME_H + +#include <kmainwindow.h> +#include <kmenubar.h> +#include <libkmid/midiout.h> +#include <libkmid/player.h> +#include <libkmid/track.h> +#include <qtimer.h> +#include <kdelibs_export.h> + +class KApplication; +class KConfig; +class kmidClient; +class KToolBar; +class QDragEvent; +class KAccel; + +class KDE_EXPORT kmidFrame : public KMainWindow +{ + Q_OBJECT +private: +#ifdef KMidDEBUG + long passcount; +#endif + + MidiOut *Midi; + MidiPlayer *Player; +/* + int playerProcessID; + PlayerController *pctl; + + int donttoggle; + + QPopupMenu *m_file; + QPopupMenu *m_song; + QPopupMenu *m_collections; + QPopupMenu *m_options; + QPopupMenu *m_help; +*/ + KAccel *kKeysAccel; +protected: + int autoAddSongToCollection(const QString& filename=QString::null,int setactive=1); + + + virtual void saveProperties(KConfig *kcfg); + virtual void readProperties(KConfig *kcfg); + +// virtual void closeEvent(QCloseEvent *e); + + void dragEnterEvent(QDragEnterEvent* e); + void dropEvent ( QDropEvent * event ); + + +public: + kmidFrame(const char *name=0); + virtual ~kmidFrame(); + +public slots: + + void file_Open(); + void file_SaveLyrics(); + void song_stopPause(); // release the pause button and quit the pause mode + void song_Loop(); + void collect_organize(); + void collect_PlayOrder(int i); + void collect_AutoAdd(); + void options_FileType(int i); + void options_DisplayEvents(int i); + void options_AutomaticText(); + void options_ShowVolumeBar(); + void options_ShowChannelView(); + void options_ChannelViewOptions(); + void options_FontChange(); + + void options_MidiSetup(); + void spacePressed(); + + + virtual void openURL( const QString s ); +/* virtual void play(); + virtual void pause(); + virtual void stop(); + virtual void rewind(); + virtual void forward(); + virtual void seek(int ms); + virtual void prevSong(); + virtual void nextSong(); + virtual void setSongLoop(int i); + virtual void setVolume(int i); + virtual void setTempo(int i); + virtual void setSongType( int i ); + virtual void setLyricEvents( int i ); + virtual void selectSong(int i); + virtual void setActiveCollection( int i ); + virtual void setCollectionPlayMode(int i); + virtual void setMidiDevice(int i); +*/ + void urlDrop_slot(class QDropEvent *); + + void rechooseTextEvent(); + + void channelViewDestroyed(); + void shuttingDown(); + +private: + kmidClient *kmidclient; +}; + +#endif diff --git a/kmid/kmidui.rc b/kmid/kmidui.rc new file mode 100644 index 00000000..8553ad2e --- /dev/null +++ b/kmid/kmidui.rc @@ -0,0 +1,44 @@ +<!DOCTYPE kpartgui> +<kpartgui name="kmid" version="3"> +<MenuBar> + <Menu name="file"><text>&File</text> + <Action name="file_save_lyrics"/> + </Menu> + <Menu name="song"><text>&Song</text> + <Action name="song_play"/> + <Action name="song_pause"/> + <Action name="song_stop"/> + <Action name="song_previous"/> + <Action name="song_next"/> + <Action name="song_loop"/> + </Menu> + <Menu name="collections"><text>&Collections</text> + <Action name="collect_organize"/> + <Action name="play_order"/> + <Action name="collect_autoadd"/> + </Menu> + <Menu name="settings"> + <Action name="toggle_volumebar" append="show_merge"/> + <Action name="toggle_channelview" append="show_merge"/> + <Action name="file_type" append="save_merge"/> + <Action name="display_events" append="save_merge"/> + <Action name="option_automatictext" append="save_merge"/> + <Separator append="save_merge"/> + <Action name="channelview_options" append="save_merge"/> + <Action name="change_font" append="save_merge"/> + <Action name="midi_setup" append="save_merge"/> + </Menu> +</MenuBar> +<ToolBar fullWidth="true" name="mainToolBar"><text>Main Toolbar</text> + <Action name="song_previous"/> + <Action name="song_rewind"/> + <Action name="song_stop"/> + <Action name="song_pause"/> + <Action name="song_play"/> + <Action name="song_forward"/> + <Action name="song_next"/> + <Separator/> + <Action name="toggle_volumebar"/> + <Action name="toggle_channelview"/> +</ToolBar> +</kpartgui> diff --git a/kmid/ktrianglebutton.cpp b/kmid/ktrianglebutton.cpp new file mode 100644 index 00000000..61e1af96 --- /dev/null +++ b/kmid/ktrianglebutton.cpp @@ -0,0 +1,164 @@ +/************************************************************************** + + ktrianglebutton.cpp - The KTriangleButton widget (button with an arrow) + Copyright (C) 1998 Antonio Larrosa Jimenez + + 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. + + Send comments and bug fixes to larrosa@kde.org + or to Antonio Larrosa, Rio Arnoya, 10 5B, 29006 Malaga, Spain + + Note: This widget was based on KButton as found in the kdelibs/kdeui + KButton was originally copyrighted by Torben Weis (weis@kde.org) + and Matthias Ettrich (ettrich@kde.org) on 1997 + +***************************************************************************/ +#include "ktrianglebutton.h" +#include <qpainter.h> +#include <qdrawutil.h> +#include <qstyle.h> + +KTriangleButton::KTriangleButton( Direction d,QWidget *_parent, const char *name ) + : QButton( _parent , name) +{ + dir=d; + raised = FALSE; + setFocusPolicy( NoFocus ); +} + +KTriangleButton::~KTriangleButton() +{ +} + +void KTriangleButton::enterEvent( QEvent* ) +{ + if ( isEnabled() ) + { + raised = TRUE; + repaint(FALSE); + } +} + +void KTriangleButton::leaveEvent( QEvent * ) +{ + if( raised != FALSE ) + { + raised = FALSE; + repaint(); + } +} + + +void KTriangleButton::drawButton( QPainter *_painter ) +{ + paint( _painter ); +} + +void KTriangleButton::drawButtonLabel( QPainter *_painter ) +{ + paint( _painter ); +} + +void KTriangleButton::paint( QPainter *painter ) +{ + if ( isDown() || isOn() ) + { + if ( style().styleHint(QStyle::SH_GUIStyle) == WindowsStyle ) + qDrawWinButton( painter, 0, 0, width(), + height(), colorGroup(), TRUE ); + else + qDrawShadePanel( painter, 0, 0, width(), + height(), colorGroup(), TRUE, 2, 0L ); + } + else if ( raised ) + { + if ( style().styleHint(QStyle::SH_GUIStyle) == WindowsStyle ) + qDrawWinButton( painter, 0, 0, width(), height(), + colorGroup(), FALSE ); + else + qDrawShadePanel( painter, 0, 0, width(), height(), + colorGroup(), FALSE, 2, 0L ); + } + + if (dir==Right) + { + int x=width()/4; + int y=height()/6; + int l=height()-y*2; + int i=0; + int maxi=width()-2*x; + double m=(double)(l/2)/maxi; + while (i<=maxi) + { + painter->drawLine(x,y+(int)(i*m),x,y+l-(int)(i*m)); + x++; + i++; + }; + } + else if (dir==Left) + { + int x=width()/4; + int y=height()/6; + int l=height()-y*2; + int i=0; + int maxi=width()-2*x; + x=width()-x; + double m=(double)(l/2)/maxi; + while (i<=maxi) + { + painter->drawLine(x,y+(int)(i*m),x,y+l-(int)(i*m)); + x--; + i++; + }; + + }; + +} + +void KTriangleButton::mousePressEvent(QMouseEvent *e) +{ + QButton::mousePressEvent(e); + usingTimer=true; + startTimer(500); + timeCount=0; + +} + +void KTriangleButton::mouseReleaseEvent(QMouseEvent *e) +{ + usingTimer=false; + QButton::mouseReleaseEvent(e); +} + +void KTriangleButton::timerEvent(QTimerEvent *) +{ + if (!usingTimer) {killTimers();return;}; + if (timeCount==0) + { + timeCount++; + killTimers(); + startTimer(120); + } else + if (timeCount==30) + { + timeCount=-1; + killTimers(); + startTimer(80); + } + else if (timeCount>0) timeCount++; + emit clickedQuickly(); + +} +#include "ktrianglebutton.moc" diff --git a/kmid/ktrianglebutton.h b/kmid/ktrianglebutton.h new file mode 100644 index 00000000..f7bad7fd --- /dev/null +++ b/kmid/ktrianglebutton.h @@ -0,0 +1,73 @@ +/************************************************************************** + + ktrianglebutton.h - The KTriangleButton widget (button with an arrow) + Copyright (C) 1998 Antonio Larrosa Jimenez + + 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. + + Send comments and bug fixes to larrosa@kde.org + or to Antonio Larrosa, Rio Arnoya, 10 5B, 29006 Malaga, Spain + + Note: This widget was copied from KButton as found in the kdelibs/kdeui + KButton was originally copyrighted by Torben Weis (weis@kde.org) + and Matthias Ettrich (ettrich@kde.org) on 1997 + +***************************************************************************/ +#ifndef _ktrianglebutton_h_ +#define _ktrianglebutton_h_ + +#include <qbutton.h> + +class KTriangleButton : public QButton +{ + Q_OBJECT + +public: + enum Direction {Left , Right, Up, Down}; + /* + Up and Down are not implemented, feel free to implement them yourself + if you need them :-) + */ +protected: + + Direction dir; + bool usingTimer; + int timeCount; + +public: + KTriangleButton( Direction d,QWidget *_parent = 0L, const char *name = 0L ); + ~KTriangleButton(); + + virtual void leaveEvent( QEvent *_ev ); + virtual void enterEvent( QEvent *_ev ); + + virtual void drawButton( QPainter *_painter ); + virtual void drawButtonLabel( QPainter *_painter ); + + void paint( QPainter *_painter ); + +signals: + void clickedQuickly(); + +protected: + bool raised; + + virtual void mousePressEvent(QMouseEvent *e); + virtual void mouseReleaseEvent(QMouseEvent *e); + virtual void timerEvent(QTimerEvent *); + +}; + +#endif diff --git a/kmid/main.cpp b/kmid/main.cpp new file mode 100644 index 00000000..bb991d74 --- /dev/null +++ b/kmid/main.cpp @@ -0,0 +1,101 @@ +/************************************************************************** + + main.cpp - The main function for KMid + Copyright (C) 1997,98 Antonio Larrosa Jimenez + + 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. + + Send comments and bug fixes to larrosa@kde.org + or to Antonio Larrosa, Rio Arnoya, 10 5B, 29006 Malaga, Spain + +***************************************************************************/ +#include <stdlib.h> +#include <string.h> +#include <signal.h> + +#include <qwidget.h> +#include <qtextcodec.h> + +#include <kapplication.h> +#include <klocale.h> +#include <kio/job.h> +#include <kcmdlineargs.h> +#include <kaboutdata.h> + +#include "kmidframe.h" +#include "kmid_part.h" +#include "version.h" + +int main(int argc, char **argv) +{ + printf("%s Copyright (C) 1997,98,99,2000,01 Antonio Larrosa Jimenez. Malaga (Spain)\n",VERSION_TXT); + printf("KMid comes with ABSOLUTELY NO WARRANTY; for details view file COPYING\n"); + printf("This is free software, and you are welcome to redistribute it\n"); + printf("under certain conditions\n\n"); + + QTextCodec::setCodecForCStrings(QTextCodec::codecForLocale()); +/* + struct sigaction act; + act.sa_handler = SIG_DFL; + sigemptyset(&(act.sa_mask)); + act.sa_flags=0; + + sigaction(SIGINT, &act, NULL); + sigaction(SIGTERM, &act, NULL); +*/ + + KCmdLineArgs::init(argc, argv, KMidFactory::aboutData() ); + + static KCmdLineOptions options[] = + { + { "+file", I18N_NOOP("File to open"), 0 }, + KCmdLineLastOption + }; + KCmdLineArgs::addCmdLineOptions(options); + + KApplication app; + + kmidFrame *kmidframe=new kmidFrame("KMid"); + + app.setMainWidget ( kmidframe ); + + QObject::connect(&app,SIGNAL(shutDown()),kmidframe,SLOT(shuttingDown())); + + if (app.isRestored()) + { + if (kmidframe->canBeRestored(1)) kmidframe->restore(1); + } + + kmidframe->show(); + + //CT KIOJob::initStatic(); + +/* + if (app->isRestored()) + { + RESTORE(kmidFrame); + } + else + { + kmidFrame *kmidframe=new kmidFrame("KMid"); + kmidframe->show(); + }; +*/ + + + + return app.exec(); +} + diff --git a/kmid/maps/Makefile.am b/kmid/maps/Makefile.am new file mode 100644 index 00000000..d276e13e --- /dev/null +++ b/kmid/maps/Makefile.am @@ -0,0 +1,5 @@ + +maps_DATA = gm.map YamahaPSS790.map YamahaPSR500.map YamahaQY10.map +mapsdir = $(kde_datadir)/kmid/maps + +EXTRA_DIST = $(maps_DATA) diff --git a/kmid/maps/YamahaPSR500.map b/kmid/maps/YamahaPSR500.map new file mode 100644 index 00000000..16068c21 --- /dev/null +++ b/kmid/maps/YamahaPSR500.map @@ -0,0 +1,293 @@ +# Blank lines and lines beginning with # are ignored
+# This is a map for a Yamaha PSR-500 keyboard
+# This file was done by Dietmar Schnabel (thanks !)
+
+# If you make a new map, please send it to Antonio, so future releases
+# will include them.
+# Antonio Larrosa Jimenez, larrosa@kde.org
+
+# General Midi Map File
+
+DEFINE PATCHMAP
+AcusticPiano =0
+BrightPiano =0
+SynthPiano =3
+HonkyTonky =2
+ElectricPiano1=4
+ElectricPiano2=5
+Harpsichord =6
+Clavinet =8
+Celeste =9
+Glockenspiel =40
+Musicbox =41
+Vibes =40
+Marimba =41
+Xylophon =41
+TubeBell =41
+Santur =42
+HomeOrg =12
+PercussionOrg =13
+RockOrg =14
+ChurchOrg =10
+ReedOrg =11
+Accordion =16
+Harmonica =17
+Concrtna =17
+NylonGuitar =29
+AcusticGuitar =31
+JazzGuitar =24
+CleanGuitar =19
+MuteGuitar =26
+OdGuitar =18
+DistortionGuit=23
+GtrHarm =20
+AcusticBass =88
+FingerBass =89
+PickBass =87
+FretlessBass =84
+SlapBass1 =87
+SlapBass2 =87
+SynthBass1 =90
+SynthBass2 =91
+Violin =32
+Viola =33
+Cello =34
+Contrabajo =33
+Marcato =34
+Pizzicato =38
+Harp =38
+Timpani =33
+Marcato =34
+SlowStrings =35
+SynthStrings1 =36
+SynthStrings2 =75
+Choir =72
+Doo =72
+Voices =72
+OrchestraHit =37
+Trumpet =43
+Trombone =47
+Tuba =50
+MuteTrumpet =44
+FrenchHorn =49
+HitBrass =51
+SynthBrass1 =52
+SynthBrass2 =74
+SopranoSax =60
+AltoSax =61
+TenorSax =62
+BaritoneSax =63
+Oboe =57
+EnglishHorn =58
+Bassoon =59
+Clarinet =55
+Piccolo =53
+Flute =54
+Recorder =66
+WoodFlute =65
+Bottle =55
+Shakazul =55
+Whistle =68
+Ocarina =79
+SquareWave =80
+SawWave =81
+Calliope =82
+Chiflead =83
+Charang =84
+VoxLead =85
+Lead5th =86
+BassLead =87
+Fantasia =88
+WarmPad =89
+Polysyn =90
+Ghostie =91
+BowGlass =92
+MetalPad =93
+HaloPad =94
+Sweeper =95
+Aurora =72
+SoundTrack =72
+Crystal =72
+Atmosphear =72
+FreshAir =100
+Unicorn =101
+Sweeper =102
+StarTrak =103
+Sitar =104
+Banjo =105
+Shamisen =106
+Koto =107
+Kalimba =108
+BagPipes =109
+Fiddle =110
+Shannai =111
+Carillon =112
+Agogo =113
+SteelDrm =114
+WoodBlk =115
+Taiko =116
+Toms =117
+Syntom =118
+RevCymbal =119
+Fx-Fret =120
+Fx-Blow =121
+Seashore =122
+Jungle =123
+Telephon =124
+Helicopter =125
+Applause =126
+Gunshot =127
+END
+
+DEFINE KEYMAP "Drumset"
+C 0 =0
+C#0 =1
+D 0 =2
+D#0 =3
+E 0 =4
+F 0 =5
+F#0 =6
+G 0 =7
+G#0 =8
+A 0 =9
+A#0 =10
+B 0 =11
+C 1 =12
+C#1 =13
+D 1 =14
+D#1 =15
+E 1 =16
+F 1 =17
+F#1 =18
+G 1 =19
+G#1 =20
+A 1 =21
+A#1 =22
+B 1 =23
+C 2 =24
+C#2 =25
+D 2 =26
+D#2 27 Highq =27
+E 2 28 Slap =54
+F 2 29 Scratch1 =62
+F#2 30 Scratch2 =63
+G 2 31 Sticks =22
+G#2 32 SqrClick =87
+A 2 33 MetaClick=57
+A#2 34 MetBell =55
+B 2 35 Kick1 =44
+C 3 36 Kick2 =45
+C#3 37 StickRim =27
+D 3 38 Snare1 =28
+D#3 39 Claps =30
+E 3 40 snare2 =25
+F 3 41 tomlo2 =24
+F#3 42 Hihatclos=72
+G 3 43 Tomlo1 =17
+G#3 44 HihatPd =56
+A 3 45 Tommid2 =26
+A#3 46 Hihatop =35
+B 3 47 Tommid1 =18
+C 4 48 Tomhi2 =29
+C#4 49 Cymbalcrsh1 =36
+D 4 50 Tomhi1 =19
+D#4 51 Cymbalride1 =38
+E 4 52 Cymbalchina =38
+F 4 53 Cymbell =38
+F#4 54 Tamborin =47
+G 4 55 CymbalSplash=37
+G#4 56 Cowbell =31
+A 4 57 Cymbalcrash2=36
+A#4 58 Vibslap =39
+B 4 59 Cymbalride2 =39
+C 5 60 Bongohi =44
+C#5 61 Bongolo =43
+D 5 62 Congahi1 =41
+D#5 63 congahi2 =42
+E 5 64 Congalo =40
+F 5 65 Timbalehi=46
+F#5 66 Timbalelo=45
+G 5 67 Agogohi =51
+G#5 68 Agogolo =50
+A 5 69 Cabasa =32
+A#5 70 Maracas =65
+B 5 71 whistle1 =52
+C 6 72 whistle2 =53
+C#6 73 Guiro1 =74
+D 6 74 Guiro2 =74
+D#6 75 Clave =29
+E 6 76 Woodblock1=73
+F 6 77 Woodblock2=72
+F#6 78 Cuica1 =76
+G 6 79 Cuica2 =77
+G#6 80 Triangle1=13
+A 6 81 Triangle2=15
+A#6 82 Shaker =56
+B 6 83 Jingles =75
+C 7 84 Belltree =71
+C#7 85 Canstinet=85
+D 7 86 Surdo1 =86
+D#7 87 Surdo2 =87
+E 7 =88
+F 7 =89
+F#7 =90
+G 7 =91
+G#7 =92
+A 7 =93
+A#7 =94
+B 7 =95
+C 8 =96
+C#8 =97
+D 8 =98
+D#8 =99
+E 8 =100
+F 8 =101
+F#8 =102
+G 8 =103
+G#8 =104
+A 8 =105
+A#8 =106
+B 8 =107
+C 9 =108
+C#9 =109
+D 9 =110
+D#9 =111
+E 9 =112
+F 9 =113
+F#9 =114
+G 9 =115
+G#9 =116
+A 9 =117
+A#9 =118
+B 9 =119
+C 10=120
+C#10=121
+D 10=122
+D#10=123
+E 10=124
+F 10=125
+F#10=126
+G 10=127
+# This line should be ignored
+END
+
+
+DEFINE CHANNELMAP
+0 = 0
+1 = 1
+2 = 2
+3 = 3
+4 = 4
+5 = 5
+6 = 6
+7 = 7
+8 = 8
+9 = 9 Keymap "Drumset" ForcePatch 99
+10 = 10
+11 = 11
+12 = 12
+13 = 13
+14 = 14
+15 = 15
+END
+
diff --git a/kmid/maps/YamahaPSS790.map b/kmid/maps/YamahaPSS790.map new file mode 100644 index 00000000..5017832e --- /dev/null +++ b/kmid/maps/YamahaPSS790.map @@ -0,0 +1,299 @@ +# Blank lines and lines beginning with # are ignored
+# This is my a map for the Yamaha PSS-790 keyboard
+# it can be used as a template to make any new map for any
+# other keyboard.
+# If you make a new map, please send it to me, so future releases
+# will include it.
+# Antonio Larrosa Jimenez, larrosa@kde.org
+
+# Yamaha PSS-790 Map File
+
+DEFINE PATCHMAP
+AcusticPiano =3
+BrightPiano =3
+SynthPiano =54
+HonkyTonky =25
+ElectricPiano1=25
+ElectricPiano2=25
+Harpsichord =53
+Clavinet =30
+Celeste =6
+Glockenspiel =64
+Musicbox =24
+Vibes =28
+Marimba =8
+Xylophon =24
+TubeBell =95
+Santur =30
+HomeOrg =1
+PercussionOrg =2
+RockOrg =11
+ChurchOrg =29
+ReedOrg =49
+Accordion =31
+Harmonica =22
+Concrtna =3
+NylonGuitar =36
+AcusticGuitar =68
+JazzGuitar =122
+CleanGuitar =68
+MuteGuitar =12
+OdGuitar =123
+DistortionGuit=13
+GtrHarm =72
+AcusticBass =38
+FingerBass =39
+PickBass =79
+FretlessBass =80
+SlapBass1 =14
+SlapBass2 =81
+SynthBass1 =58
+SynthBass2 =86
+Violin =10
+Viola =67
+Cello =67
+Contrabajo =41
+Marcato =41
+Pizzicato =78
+Harp =37
+Timpani =66
+Marcato =41
+SlowStrings =50
+SynthStrings1 =41
+SynthStrings2 =50
+Choir =96
+Doo =94
+Voices =96
+OrchestraHit =90
+Trumpet =15
+Trombone =16
+Tuba =84
+MuteTrumpet =44
+FrenchHorn =17
+HitBrass =92
+SynthBrass1 =0
+SynthBrass2 =82
+SopranoSax =101
+AltoSax =18
+TenorSax =102
+BaritoneSax =101
+Oboe =19
+EnglishHorn =87
+Bassoon =87
+Clarinet =19
+Piccolo =103
+Flute =20
+Recorder =88
+WoodFlute =111
+Bottle =111
+Shakazul =110
+Whistle =88
+Ocarina =93
+SquareWave =54
+SawWave =54
+Calliope =22
+Chiflead =9
+Charang =19
+VoxLead =96
+Lead5th =41
+BassLead =95
+Fantasia =111
+WarmPad =51
+Polysyn =60
+Ghostie =94
+BowGlass =33
+MetalPad =9
+HaloPad =111
+Sweeper =78
+Aurora =60
+SoundTrack =84
+Crystal =60
+Atmosphear =51
+FreshAir =60
+Unicorn =93
+Sweeper =112
+StarTrak =117
+Sitar =73
+Banjo =34
+Shamisen =73
+Koto =70
+Kalimba =73
+BagPipes =11
+Fiddle =67
+Shannai =11
+Carillon =64
+Agogo =91
+SteelDrm =9
+WoodBlk =35
+Taiko =100 AllKeysTo 60
+Toms =66
+Syntom =85
+RevCymbal =100 AllKeysTo 60
+Fx-Fret =121
+Fx-Blow =94
+Seashore =100 AllKeysTo 79
+Jungle =70
+Telephon =91
+Helicopter =111
+Applause =100 AllKeysTo 79
+Gunshot =100 AllKeysTo 38
+
+END
+
+DEFINE KEYMAP "Drumset"
+C 0 =0
+C#0 =1
+D 0 =2
+D#0 =3
+E 0 =4
+F 0 =5
+F#0 =6
+G 0 =7
+G#0 =8
+A 0 =9
+A#0 =10
+B 0 =11
+C 1 =12
+C#1 =13
+D 1 =14
+D#1 =15
+E 1 =16
+F 1 =17
+F#1 =18
+G 1 =19
+G#1 =20
+A 1 =21
+A#1 =22
+B 1 =23
+C 2 =24
+C#2 =25
+D 2 =26
+D#2 27 Highq =27
+E 2 28 Slap =54
+F 2 29 Scratch1 =29
+F#2 30 Scratch2 =30
+G 2 31 Sticks =46
+G#2 32 SqrClick =87
+A 2 33 MetaClick=57
+A#2 34 MetBell =55
+B 2 35 AcousticBassDrum=44
+C 3 36 BassDrum1=47
+C#3 37 StickRim =46
+D 3 38 AcSnare =47
+D#3 39 Claps =63
+E 3 40 ElectSnare =49
+F 3 41 LowFloorTom =48
+F#3 42 Hihatclos =57
+G 3 43 HighFloorTom=50
+G#3 44 PedalHihat =80
+A 3 45 LowTom =47
+A#3 46 OpenHihat =59
+B 3 47 LowMidTom =48
+C 4 48 HiMidTom =50
+C#4 49 Cymbalcrsh1 =60
+D 4 50 HiTom =53
+D#4 51 Cymbalride1 =63
+E 4 52 Cymbalchina =60
+F 4 53 RideBell =62
+F#4 54 Tambourin =71
+G 4 55 CymbalSplash=61
+G#4 56 Cowbell =55
+A 4 57 Cymbalcrash2=60
+A#4 58 Vibraslap =79
+B 4 59 Cymbalride2 =62
+C 5 60 Bongohi =68
+C#5 61 Bongolo =67
+D 5 62 MuteHiConga =66
+D#5 63 OpenHiConga =65
+E 5 64 LowConga =64
+F 5 65 HiTimbale =70
+F#5 66 LoTimbale =69
+G 5 67 HiAgogo =75
+G#5 68 LoAgogo =74
+A 5 69 Cabasa =56
+A#5 70 Maracas =56
+B 5 71 ShortWhistle=78
+C 6 72 LongWhistle =78
+C#6 73 ShortGuiro =79
+D 6 74 LongGuiro =71
+D#6 75 Clave =72
+E 6 76 HiWoodBlock =73
+F 6 77 LoWoodBlock =72
+F#6 78 MuteCuica =77
+G 6 79 OpenCuica =76
+G#6 80 MuteTriangle=37
+A 6 81 OpenTriangle=39
+A#6 82 Shaker =56
+B 6 83 Jingles =75
+C 7 84 Belltree =63
+C#7 85 Canstinet=85
+D 7 86 Surdo1 =86
+D#7 87 Surdo2 =87
+E 7 =88
+F 7 =89
+F#7 =90
+G 7 =91
+G#7 =92
+A 7 =93
+A#7 =94
+B 7 =95
+C 8 =96
+C#8 =97
+D 8 =98
+D#8 =99
+E 8 =100
+F 8 =101
+F#8 =102
+G 8 =103
+G#8 =104
+A 8 =105
+A#8 =106
+B 8 =107
+C 9 =108
+C#9 =109
+D 9 =110
+D#9 =111
+E 9 =112
+F 9 =113
+F#9 =114
+G 9 =115
+G#9 =116
+A 9 =117
+A#9 =118
+B 9 =119
+C 10=120
+C#10=121
+D 10=122
+D#10=123
+E 10=124
+F 10=125
+F#10=126
+G 10=127
+# This line should be ignored
+END
+
+
+DEFINE CHANNELMAP
+0 = 0
+1 = 1
+2 = 2
+3 = 3
+4 = 4
+5 = 5
+6 = 6
+7 = 7
+8 = 8
+9 = 15 Keymap "Drumset" ForcePatch 100
+10 = 10
+11 = 11
+12 = 12
+13 = 13
+14 = 14
+15 = 9
+END
+
+OPTIONS
+PitchBenderRatio = 672
+MapExpressionToVolumeEvents
+END
+
diff --git a/kmid/maps/YamahaQY10.map b/kmid/maps/YamahaQY10.map new file mode 100644 index 00000000..1a4914b4 --- /dev/null +++ b/kmid/maps/YamahaQY10.map @@ -0,0 +1,305 @@ +# Midi map file for the Yamaha QY10 "walkstation", a basic sequencer / tone +# module. + +# Provided by Malcolm Tyrrell. If there is a problem with this file, please +# e-mail tyrrelmr@cs.tcd.ie + +# If you make a new map, please send it to Antonio, so future releases +# will include them. +# Antonio Larrosa Jimenez, larrosa@kde.org + +# Yamaha QY10 Map File + +DEFINE PATCHMAP +AcusticPiano =0 +BrightPiano =0 +SynthPiano =1 +HonkyTonky =0 +ElectricPiano1=1 +ElectricPiano2=2 +Harpsichord =3 +Clavinet =3 +Celeste =18 +Glockenspiel =18 +Musicbox =20 +Vibes =19 +Marimba =18 +Xylophon =20 +TubeBell =19 +Santur =12 +HomeOrg =4 +PercussionOrg =4 +RockOrg =4 +ChurchOrg =5 +ReedOrg =5 +Accordion =5 +Harmonica =23 +Concrtna =23 +NylonGuitar =12 +AcusticGuitar =12 +JazzGuitar =9 +CleanGuitar =9 +MuteGuitar =11 +OdGuitar =9 +DistortionGuit=10 +GtrHarm =25 +AcusticBass =13 +FingerBass =14 +PickBass =14 +FretlessBass =13 +SlapBass1 =15 +SlapBass2 =15 +SynthBass1 =16 +SynthBass2 =16 +Violin =23 +Viola =23 +Cello =23 +Contrabajo =23 +Marcato =6 +Pizzicato =16 +Harp =12 +Timpani =20 +Marcato =6 +SlowStrings =6 +SynthStrings1 =22 +SynthStrings2 =22 +Choir =27 +Doo =21 +Voices =21 +OrchestraHit =8 +Trumpet =26 +Trombone =26 +Tuba =21 +MuteTrumpet =8 +FrenchHorn =26 +HitBrass =8 +SynthBrass1 =21 +SynthBrass2 =21 +SopranoSax =26 +AltoSax =26 +TenorSax =26 +BaritoneSax =26 +Oboe =27 +EnglishHorn =26 +Bassoon =27 +Clarinet =27 +Piccolo =27 +Flute =27 +Recorder =27 +WoodFlute =27 +Bottle =27 +Shakazul =27 +Whistle =27 +Ocarina =27 +SquareWave =28 +SawWave =28 +Calliope =29 +Chiflead =29 +Charang =24 +VoxLead =21 +Lead5th =21 +BassLead =21 +Fantasia =24 +WarmPad =21 +Polysyn =22 +Ghostie =27 +BowGlass =26 +MetalPad =21 +HaloPad =27 +Sweeper =24 +Aurora =31 +SoundTrack =21 +Crystal =19 +Atmosphear =24 +FreshAir =21 +Unicorn =24 +Sweeper =24 +StarTrak =21 +Sitar =9 +Banjo =9 +Shamisen =12 +Koto =12 +Kalimba =18 +BagPipes =28 +Fiddle =28 +Shannai =23 +Carillon =19 +Agogo =20 +SteelDrm =18 +WoodBlk =20 +Taiko =20 +Toms =18 +Syntom =18 +RevCymbal =31 +Fx-Fret =31 +Fx-Blow =31 +Seashore =31 +Jungle =31 +Telephon =5 +Helicopter =31 +Applause =31 +Gunshot =31 +END + +DEFINE KEYMAP "Drumset" +C 0 =0 +C#0 =1 +D 0 =2 +D#0 =3 +E 0 =4 +F 0 =5 +F#0 =6 +G 0 =7 +G#0 =8 +A 0 =9 +A#0 =10 +B 0 =11 +C 1 =12 +C#1 =13 +D 1 =14 +D#1 =15 +E 1 =16 +F 1 =17 +F#1 =18 +G 1 =19 +G#1 =20 +A 1 =21 +A#1 =22 +B 1 =23 +C 2 =24 +C#2 =25 +D 2 =26 +# What is a high q? +D#2 27 Highq =40 +E 2 28 Slap =37 +F 2 29 Scratch1 =23 +F#2 30 Scratch2 =48 +G 2 31 Sticks =21 +G#2 32 SqrClick =42 +A 2 33 MetaClick=42 +A#2 34 MetBell =43 +B 2 35 Kick1 =36 +C 3 36 Kick2 =12 +C#3 37 StickRim =21 +D 3 38 Snare1 =15 +D#3 39 Claps =19 +E 3 40 snare2 =14 +F 3 41 tomlo2 =16 +F#3 42 Hihatclos=23 +G 3 43 Tomlo1 =16 +G#3 44 HihatPd =23 +A 3 45 Tommid2 =17 +A#3 46 Hihatop =24 +B 3 47 Tommid1 =17 +C 4 48 Tomhi2 =18 +C#4 49 Cymbalcrsh1 =20 +D 4 50 Tomhi1 =18 +D#4 51 Cymbalride1 =22 +E 4 52 Cymbalchina =22 +F 4 53 Cymbell =22 +F#4 54 Tamborin =21 +G 4 55 CymbalSplash=20 +G#4 56 Cowbell =37 +A 4 57 Cymbalcrash2=20 +A#4 58 Vibslap =0 +B 4 59 Cymbalride2 =22 +C 5 60 Bongohi =41 +C#5 61 Bongolo =40 +D 5 62 Congahi1 =41 +D#5 63 congahi2 =41 +E 5 64 Congalo =40 +F 5 65 Timbalehi=46 +F#5 66 Timbalelo=45 +G 5 67 Agogohi =44 +G#5 68 Agogolo =43 +A 5 69 Cabasa =48 +A#5 70 Maracas =48 +B 5 71 whistle1 =0 +C 6 72 whistle2 =0 +C#6 73 Guiro1 =0 +D 6 74 Guiro2 =0 +D#6 75 Clave =44 +E 6 76 Woodblock1=40 +F 6 77 Woodblock2=41 +# Don't know about the following two +F#6 78 Cuica1 =0 +G 6 79 Cuica2 =0 +G#6 80 Triangle1=44 +A 6 81 Triangle2=44 +A#6 82 Shaker =48 +B 6 83 Jingles =23 +C 7 84 Belltree =0 +C#7 85 Canstinet=21 +D 7 86 Surdo1 =16 +D#7 87 Surdo2 =17 +E 7 =88 +F 7 =89 +F#7 =90 +G 7 =91 +G#7 =92 +A 7 =93 +A#7 =94 +B 7 =95 +C 8 =96 +C#8 =97 +D 8 =98 +D#8 =99 +E 8 =100 +F 8 =101 +F#8 =102 +G 8 =103 +G#8 =104 +A 8 =105 +A#8 =106 +B 8 =107 +C 9 =108 +C#9 =109 +D 9 =110 +D#9 =111 +E 9 =112 +F 9 =113 +F#9 =114 +G 9 =115 +G#9 =116 +A 9 =117 +A#9 =118 +B 9 =119 +C 10=120 +C#10=121 +D 10=122 +D#10=123 +E 10=124 +F 10=125 +F#10=126 +G 10=127 +END + + +DEFINE CHANNELMAP +# The information on channels 7-8 and 11-15 is ignored since the QY10 is only +# 8 part multi-timbral. The polyphony should be okay. +0 = 0 +1 = 1 +2 = 2 +3 = 3 +4 = 4 +5 = 5 +6 = 6 +# The next two channels are ignored +7 = 9 +8 = 8 +# Play GM channel 9 (drums) on QY10 track 7 (rhythm track) +9 = 7 Keymap "Drumset" ForcePatch 30 +# All the following channels are ignored. +10 = 10 +11 = 11 +12 = 12 +13 = 13 +14 = 14 +15 = 15 +END + +# I don't think the QY10 responds to Expression Events, so... +OPTIONS +MapExpressionToVolumeEvents +END diff --git a/kmid/maps/gm.map b/kmid/maps/gm.map new file mode 100644 index 00000000..fd188ec0 --- /dev/null +++ b/kmid/maps/gm.map @@ -0,0 +1,290 @@ +# Blank lines and lines beginning with # are ignored +# This is a map for any General Midi synthesizer +# If you make a new map, please send it to me, so future releases +# will include them. +# Antonio Larrosa Jimenez, larrosa@kde.org + +# General Midi Map File + +DEFINE PATCHMAP +AcusticPiano =0 +BrightPiano =1 +SynthPiano =2 +HonkyTonky =3 +ElectricPiano1=4 +ElectricPiano2=5 +Harpsichord =6 +Clavinet =7 +Celeste =8 +Glockenspiel =9 +Musicbox =10 +Vibes =11 +Marimba =12 +Xylophon =13 +TubeBell =14 +Santur =15 +HomeOrg =16 +PercussionOrg =17 +RockOrg =18 +ChurchOrg =19 +ReedOrg =20 +Accordion =21 +Harmonica =22 +Concrtna =23 +NylonGuitar =24 +AcusticGuitar =25 +JazzGuitar =26 +CleanGuitar =27 +MuteGuitar =28 +OdGuitar =29 +DistortionGuit=30 +GtrHarm =31 +AcusticBass =32 +FingerBass =33 +PickBass =34 +FretlessBass =35 +SlapBass1 =36 +SlapBass2 =37 +SynthBass1 =38 +SynthBass2 =39 +Violin =40 +Viola =41 +Cello =42 +Contrabajo =43 +Marcato =44 +Pizzicato =45 +Harp =46 +Timpani =47 +Marcato =48 +SlowStrings =49 +SynthStrings1 =50 +SynthStrings2 =51 +Choir =52 +Doo =53 +Voices =54 +OrchestraHit =55 +Trumpet =56 +Trombone =57 +Tuba =58 +MuteTrumpet =59 +FrenchHorn =60 +HitBrass =61 +SynthBrass1 =62 +SynthBrass2 =63 +SopranoSax =64 +AltoSax =65 +TenorSax =66 +BaritoneSax =67 +Oboe =68 +EnglishHorn =69 +Bassoon =70 +Clarinet =71 +Piccolo =72 +Flute =73 +Recorder =74 +WoodFlute =75 +Bottle =76 +Shakazul =77 +Whistle =78 +Ocarina =79 +SquareWave =80 +SawWave =81 +Calliope =82 +Chiflead =83 +Charang =84 +VoxLead =85 +Lead5th =86 +BassLead =87 +Fantasia =88 +WarmPad =89 +Polysyn =90 +Ghostie =91 +BowGlass =92 +MetalPad =93 +HaloPad =94 +Sweeper =95 +Aurora =96 +SoundTrack =97 +Crystal =98 +Atmosphear =99 +FreshAir =100 +Unicorn =101 +Sweeper =102 +StarTrak =103 +Sitar =104 +Banjo =105 +Shamisen =106 +Koto =107 +Kalimba =108 +BagPipes =109 +Fiddle =110 +Shannai =111 +Carillon =112 +Agogo =113 +SteelDrm =114 +WoodBlk =115 +Taiko =116 +Toms =117 +Syntom =118 +RevCymbal =119 +Fx-Fret =120 +Fx-Blow =121 +Seashore =122 +Jungle =123 +Telephon =124 +Helicopter =125 +Applause =126 +Gunshot =127 +END + +DEFINE KEYMAP "Drumset" +C 0 =0 +C#0 =1 +D 0 =2 +D#0 =3 +E 0 =4 +F 0 =5 +F#0 =6 +G 0 =7 +G#0 =8 +A 0 =9 +A#0 =10 +B 0 =11 +C 1 =12 +C#1 =13 +D 1 =14 +D#1 =15 +E 1 =16 +F 1 =17 +F#1 =18 +G 1 =19 +G#1 =20 +A 1 =21 +A#1 =22 +B 1 =23 +C 2 =24 +C#2 =25 +D 2 =26 +D#2 27 Highq =27 +E 2 28 Slap =28 +F 2 29 Scratch1 =29 +F#2 30 Scratch2 =30 +G 2 31 Sticks =31 +G#2 32 SqrClick =32 +A 2 33 MetaClick=33 +A#2 34 MetBell =34 +B 2 35 Kick1 =35 +C 3 36 Kick2 =36 +C#3 37 StickRim =37 +D 3 38 Snare1 =38 +D#3 39 Claps =39 +E 3 40 snare2 =40 +F 3 41 tomlo2 =41 +F#3 42 Hihatclos=42 +G 3 43 Tomlo1 =43 +G#3 44 HihatPd =44 +A 3 45 Tommid2 =45 +A#3 46 Hihatop =46 +B 3 47 Tommid1 =47 +C 4 48 Tomhi2 =48 +C#4 49 Cymbalcrsh1 =49 +D 4 50 Tomhi1 =50 +D#4 51 Cymbalride1 =51 +E 4 52 Cymbalchina =52 +F 4 53 Cymbell =53 +F#4 54 Tamborin =54 +G 4 55 CymbalSplash=55 +G#4 56 Cowbell =56 +A 4 57 Cymbalcrash2=57 +A#4 58 Vibslap =58 +B 4 59 Cymbalride2 =59 +C 5 60 Bongohi =60 +C#5 61 Bongolo =61 +D 5 62 Congahi1 =62 +D#5 63 congahi2 =63 +E 5 64 Congalo =64 +F 5 65 Timbalehi=65 +F#5 66 Timbalelo=66 +G 5 67 Agogohi =67 +G#5 68 Agogolo =68 +A 5 69 Cabasa =69 +A#5 70 Maracas =70 +B 5 71 whistle1 =71 +C 6 72 whistle2 =72 +C#6 73 Guiro1 =73 +D 6 74 Guiro2 =74 +D#6 75 Clave =75 +E 6 76 Woodblock1=76 +F 6 77 Woodblock2=77 +F#6 78 Cuica1 =78 +G 6 79 Cuica2 =79 +G#6 80 Triangle1=80 +A 6 81 Triangle2=81 +A#6 82 Shaker =82 +B 6 83 Jingles =83 +C 7 84 Belltree =84 +C#7 85 Canstinet=85 +D 7 86 Surdo1 =86 +D#7 87 Surdo2 =87 +E 7 =88 +F 7 =89 +F#7 =90 +G 7 =91 +G#7 =92 +A 7 =93 +A#7 =94 +B 7 =95 +C 8 =96 +C#8 =97 +D 8 =98 +D#8 =99 +E 8 =100 +F 8 =101 +F#8 =102 +G 8 =103 +G#8 =104 +A 8 =105 +A#8 =106 +B 8 =107 +C 9 =108 +C#9 =109 +D 9 =110 +D#9 =111 +E 9 =112 +F 9 =113 +F#9 =114 +G 9 =115 +G#9 =116 +A 9 =117 +A#9 =118 +B 9 =119 +C 10=120 +C#10=121 +D 10=122 +D#10=123 +E 10=124 +F 10=125 +F#10=126 +G 10=127 +END + + +DEFINE CHANNELMAP +0 = 0 +1 = 1 +2 = 2 +3 = 3 +4 = 4 +5 = 5 +6 = 6 +7 = 7 +8 = 8 +9 = 9 +10 = 10 +11 = 11 +12 = 12 +13 = 13 +14 = 14 +15 = 15 +END + diff --git a/kmid/midicfgdlg.cpp b/kmid/midicfgdlg.cpp new file mode 100644 index 00000000..c33b5043 --- /dev/null +++ b/kmid/midicfgdlg.cpp @@ -0,0 +1,138 @@ +/************************************************************************** + + midicfgdlg.cpp - The midi config dialog + Copyright (C) 1997,98 Antonio Larrosa Jimenez + + 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. + + Send comments and bug fixes to larrosa@kde.org + or to Antonio Larrosa, Rio Arnoya, 10 5B, 29006 Malaga, Spain + +***************************************************************************/ +#include <qpushbutton.h> +#include <qlistbox.h> +#include <qlabel.h> +#include <qlayout.h> + +#include <kapplication.h> +#include <kfiledialog.h> +#include <kmessagebox.h> +#include <klocale.h> +#include <libkmid/deviceman.h> + +#include "midicfgdlg.h" +#include "version.h" +#include <kglobal.h> +#include <kstandarddirs.h> + +MidiConfigDialog::MidiConfigDialog(DeviceManager *dm, + QWidget *parent,const char *name) : KDialogBase(parent,name,TRUE, + i18n("Configure MIDI Devices"), KDialogBase::Ok|KDialogBase::Cancel) +{ + setMinimumSize(360,240); + QWidget *page = new QWidget( this ); + setMainWidget(page); + + QVBoxLayout *topLayout=new QVBoxLayout(page, 0, spacingHint()); + QLabel *label=new QLabel(i18n("Select the MIDI device you want to use:"),page); + topLayout->addWidget(label); + mididevices=new QListBox(page,"midideviceslist"); + topLayout->addWidget(mididevices,3); + connect(mididevices,SIGNAL(highlighted(int)),SLOT(deviceselected(int))); + devman=dm; + QString temp; + for (int i=0;i<devman->midiPorts()+devman->synthDevices();i++) + { + if (strcmp(devman->type(i),"")!=0) + temp = QString("%1 - %2").arg(devman->name(i)).arg(devman->type(i)); + else + temp = devman->name(i); + + mididevices->insertItem(temp,i); + }; + selecteddevice=devman->defaultDevice(); + mididevices->setCurrentItem(selecteddevice); + + QLabel *label2=new QLabel(i18n("Use the MIDI map:"),page); + topLayout->addWidget(label2); + + + if (selectedmap!=NULL) delete selectedmap; + if (strcmp(devman->midiMapFilename(),"")==0) + selectedmap=NULL; + else + { + selectedmap=new char[strlen(devman->midiMapFilename())+1]; + strcpy(selectedmap,devman->midiMapFilename()); + } + + if (selectedmap!=NULL) maplabel=new QLabel(selectedmap,page); + else maplabel=new QLabel(i18n("None"),page); + + topLayout->addWidget(maplabel); + + QHBoxLayout *hbox=new QHBoxLayout(topLayout); + hbox->addStretch(1); + mapbrowse=new QPushButton(i18n("Browse..."),page); + hbox->addWidget(mapbrowse); + connect(mapbrowse,SIGNAL(clicked()),SLOT(browseMap()) ); + + mapnone=new QPushButton(i18n("None"),page); + hbox->addWidget(mapnone); + connect(mapnone,SIGNAL(clicked()),SLOT(noMap()) ); + + topLayout->addStretch(1); + +} + +void MidiConfigDialog::deviceselected(int idx) +{ + selecteddevice=idx; +} + +void MidiConfigDialog::browseMap() +{ + QString path = KGlobal::dirs()->findAllResources("appdata", "maps/*.map").last(); + path.truncate(path.findRev('/')); + + KURL url = KFileDialog::getOpenURL(path,"*.map",this); + + if( url.isEmpty() ) + return; + + if( !url.isLocalFile() ) + { + KMessageBox::sorry( 0L, i18n( "Only local files are currently supported." ) ); + return; + } + + QString filename = url.path(); + + delete selectedmap; + selectedmap=new char[filename.length()+1]; + strcpy(selectedmap,QFile::encodeName(filename)); + maplabel->setText(selectedmap); +} + +void MidiConfigDialog::noMap() +{ + if (selectedmap!=NULL) {delete selectedmap;selectedmap=NULL;}; + maplabel->setText(i18n("None")); +} + +int MidiConfigDialog::selecteddevice=0; +char *MidiConfigDialog::selectedmap=NULL; + +#include "midicfgdlg.moc" diff --git a/kmid/midicfgdlg.h b/kmid/midicfgdlg.h new file mode 100644 index 00000000..37417b36 --- /dev/null +++ b/kmid/midicfgdlg.h @@ -0,0 +1,60 @@ +/************************************************************************** + + midicfgdlg.h - The midi config dialog + Copyright (C) 1997,98 Antonio Larrosa Jimenez + + 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. + + Send comments and bug fixes to larrosa@kde.org + or to Antonio Larrosa, Rio Arnoya, 10 5B, 29006 Malaga, Spain + +***************************************************************************/ +#ifndef _midicfgdlg_h_ +#define _midicfgdlg_h_ + +#include <kdialogbase.h> + +class DeviceManager; + +class QLabel; +class QPushButton; +class QListBox; +class MidiConfigDialog : public KDialogBase +{ + Q_OBJECT + +public: + + MidiConfigDialog(DeviceManager *dm,QWidget *parent,const char *name); + +public slots: + void deviceselected(int idx); + void browseMap(); + void noMap(); + +private: + QLabel *maplabel; + QListBox *mididevices; + QPushButton *mapbrowse; + QPushButton *mapnone; + + DeviceManager *devman; + +public: + static int selecteddevice; + static char *selectedmap; +}; + +#endif diff --git a/kmid/pics/Makefile.am b/kmid/pics/Makefile.am new file mode 100644 index 00000000..4bf75950 --- /dev/null +++ b/kmid/pics/Makefile.am @@ -0,0 +1,3 @@ +kmidicondir = $(kde_datadir)/kmid/icons +kmidicon_ICON = AUTO + diff --git a/kmid/pics/cr16-action-piano.png b/kmid/pics/cr16-action-piano.png Binary files differnew file mode 100644 index 00000000..29536a0a --- /dev/null +++ b/kmid/pics/cr16-action-piano.png diff --git a/kmid/pics/cr16-action-volume.png b/kmid/pics/cr16-action-volume.png Binary files differnew file mode 100644 index 00000000..3b75a38c --- /dev/null +++ b/kmid/pics/cr16-action-volume.png diff --git a/kmid/pics/cr22-action-piano.png b/kmid/pics/cr22-action-piano.png Binary files differnew file mode 100644 index 00000000..226e4444 --- /dev/null +++ b/kmid/pics/cr22-action-piano.png diff --git a/kmid/pics/cr22-action-volume.png b/kmid/pics/cr22-action-volume.png Binary files differnew file mode 100644 index 00000000..e87c5147 --- /dev/null +++ b/kmid/pics/cr22-action-volume.png diff --git a/kmid/pics/cr32-action-piano.png b/kmid/pics/cr32-action-piano.png Binary files differnew file mode 100644 index 00000000..9d75a570 --- /dev/null +++ b/kmid/pics/cr32-action-piano.png diff --git a/kmid/pics/cr32-action-volume.png b/kmid/pics/cr32-action-volume.png Binary files differnew file mode 100644 index 00000000..0e1f3dec --- /dev/null +++ b/kmid/pics/cr32-action-volume.png diff --git a/kmid/qslidertime.cpp b/kmid/qslidertime.cpp new file mode 100644 index 00000000..be5fdab2 --- /dev/null +++ b/kmid/qslidertime.cpp @@ -0,0 +1,120 @@ +/************************************************************************** + + kslidertime.cpp - A widget that displays time tags under a KSlider + Copyright (C) 1997,98 Antonio Larrosa Jimenez + + 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. + + Send comments and bug fixes to larrosa@kde.org + or to Antonio Larrosa, Rio Arnoya, 10 5B, 29006 Malaga, Spain + +***************************************************************************/ +#include "qslidertime.h" +#include <qwidget.h> +#include <qpainter.h> +#include <stdio.h> + +#define ARROW_LENGTH 13 + +QSliderTime::QSliderTime( QSlider *ksl, QWidget *parent, const char *name) + : QWidget (parent,name) +{ +kslider=ksl; + +QPainter painter; +QFontMetrics qfmt(painter.font()); +fontheight=qfmt.height(); + +} + +char *QSliderTime::formatMillisecs(int ms,char *tmp) +{ + if (ms<60000) + { + sprintf(tmp,"0:%02d",ms/1000); + } + else + sprintf(tmp,"%d:%02d",ms/60000,(ms%60000)/1000); +return tmp; +} + +void QSliderTime::paintEvent( QPaintEvent * ) +{ + QPainter painter(this); + +// erase(); + drawTimeMarks(&painter); +} + +int quantizeTimeStep(int t) +{ +if (t<=2000) t=2000; + else if (t<=5000) t=5000; + else if (t<=10000) t=10000; + else if (t<=15000) t=15000; + else if (t<=30000) t=30000; + else if (t<=60000) t=60000; + else if (t<=120000) t=120000; +return t; +} + +void QSliderTime::drawTimeMarks(QPainter *painter) +{ +if (kslider==NULL) return; + int i; + int maxV = kslider->maxValue(); + QFontMetrics qfmt(painter->font()); + fontheight=qfmt.height(); + int ntimetags = width()/(qfmt.width("-88:88-")); + int timestep; + if (ntimetags>1) timestep = maxV/(ntimetags); + else timestep=maxV; + timestep = quantizeTimeStep(timestep); + ntimetags = maxV/timestep; + + // draw time tags (only in horizontal !!) + int posy=qfmt.height(); + char *tmp=new char[100]; + int pos=0; + int deltapos=0; + formatMillisecs(0,tmp); + painter->drawText( 0, posy,tmp); + for ( i = timestep; i <= maxV - timestep; i += timestep ) + { + pos = (width()-10) * i / maxV + 5; + formatMillisecs(i,tmp); + deltapos=qfmt.width(tmp)/2; + painter->drawText( pos-deltapos, posy,tmp); + } + + pos = width()- 5; + formatMillisecs(maxV,tmp); + deltapos=qfmt.width(tmp); + + painter->drawText( pos-deltapos, posy,tmp); + +} + + +QSize QSliderTime::sizeHint() +{ + return QSize(10,fontheight+2); +} + +QSizePolicy QSliderTime::sizePolicy() +{ + return QSizePolicy(QSizePolicy::Expanding,QSizePolicy::Fixed); +} +#include "qslidertime.moc" diff --git a/kmid/qslidertime.h b/kmid/qslidertime.h new file mode 100644 index 00000000..4b42d7d9 --- /dev/null +++ b/kmid/qslidertime.h @@ -0,0 +1,56 @@ +/************************************************************************** + + kslidertime.h - A widget that displays time tags under a KSlider + Copyright (C) 1997,98 Antonio Larrosa Jimenez + + 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. + + Send comments and bug fixes to larrosa@kde.org + or to Antonio Larrosa, Rio Arnoya, 10 5B, 29006 Malaga, Spain + +***************************************************************************/ +#ifndef _kslidertime_h_ +#define _kslidertime_h_ + +#include <qslider.h> + +class QWidget; + +class QSliderTime : public QWidget +{ + Q_OBJECT +private: + + QSlider *kslider; + +int fontheight; +public: + + QSliderTime( QSlider *ksl, QWidget *parent = NULL, const char *name = NULL ); + + int getFontHeight(void) {return fontheight;}; + + QSize sizeHint(); + QSizePolicy sizePolicy(); + +private: + + virtual void paintEvent( QPaintEvent * ); + void drawTimeMarks(QPainter *painter); + + char *formatMillisecs(int ms,char *tmp); +}; + +#endif diff --git a/kmid/randomlist.cpp b/kmid/randomlist.cpp new file mode 100644 index 00000000..5ac736a9 --- /dev/null +++ b/kmid/randomlist.cpp @@ -0,0 +1,103 @@ +/************************************************************************** + + randomlist.cpp - Some "random functions" :-) + Copyright (C) 1997,98 Antonio Larrosa Jimenez + + 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. + + Send comments and bug fixes to larrosa@kde.org + or to Antonio Larrosa, Rio Arnoya, 10 5B, 29006 Malaga, Spain + +***************************************************************************/ +#include "randomlist.h" +#include <stdlib.h> +#include <stdio.h> + +#define RAND_UNIFORM (double)rand()/(double)RAND_MAX + +int random_discrete(double *distrib,int n) +{ + int i=0; + double g=0.0; + double z=0.0; + while ((z==0.0)||(z==1.0)) z=RAND_UNIFORM; + while ((g<z)&&(i<n)) + { + g+=distrib[i]; + i++; + }; + return i-1; +} + +double *generate_discrete_uniform_distrib(int n) +{ + double *distrib=new double[n]; + + for (int i=0;i<n;i++) + distrib[i]=1.0/(double)n; + + return distrib; +} + +void remove_lmn_from_discrete_distrib(int k,double *distrib,int n,int used=0) +{ + int i; + if (used==0) //guess how many values of the v.a. are strictly positive + { + for (i=0;i<n;i++) if (distrib[i]>0) used++; + }; + used--; // k will no longer be used :-) + if (used==0) return; + double piece=distrib[k]/(double)used; + distrib[k]=0.0; + for (i=0;i<n;i++) if (distrib[i]>0) distrib[i]+=piece; +} + +void show_distrib(double *distrib,int n) +{ + printf("("); + for (int j=0;j<n;j++) printf("%g,",distrib[j]); + printf(")\n"); +} + +int *generate_random_list(int n) +{ + if (n==0) return NULL; + int *list=new int[n]; + double *distrib=generate_discrete_uniform_distrib(n); + int used=n; + int x; + int i=1; + while (used>0) + { + x=random_discrete(distrib,n); + list[x]=i; + i++; + remove_lmn_from_discrete_distrib(x,distrib,n,used); + used--; + }; + delete distrib; + + return list; +} + +int *generate_list(int n) +{ + int *list=new int[n]; + for (int i=0;i<n;i++) + list[i]=i+1; + + return list; +} diff --git a/kmid/randomlist.h b/kmid/randomlist.h new file mode 100644 index 00000000..e351aaad --- /dev/null +++ b/kmid/randomlist.h @@ -0,0 +1,34 @@ +/************************************************************************** + + randomlist.h - Some "random functions" :-) + Copyright (C) 1997,98 Antonio Larrosa Jimenez + + 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. + + Send comments and bug fixes to larrosa@kde.org + or to Antonio Larrosa, Rio Arnoya, 10 5B, 29006 Malaga, Spain + +***************************************************************************/ + +#ifndef _RANDOMLIST_H +#define _RANDOMLIST_H + +// Returns a list (created with new) of num elements, filled with 1,2,..., num +// at random places. +int *generate_random_list(int num); + +int *generate_list(int num); + +#endif diff --git a/kmid/rhythmview.cpp b/kmid/rhythmview.cpp new file mode 100644 index 00000000..2b9136aa --- /dev/null +++ b/kmid/rhythmview.cpp @@ -0,0 +1,108 @@ +/************************************************************************** + + rhythmview.cpp - The RhythmView widget + Copyright (C) 1998 Antonio Larrosa Jimenez + + 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. + + Send comments and bug fixes to larrosa@kde.org + or to Antonio Larrosa, Rio Arnoya, 10 5B, 29006 Malaga, Spain + +***************************************************************************/ +#include "rhythmview.h" + +RhythmView::RhythmView (QWidget *parent, const char *name) : QWidget (parent,name) +{ + lamps=NULL; + setRhythm(4,4); +} + +RhythmView::~RhythmView() +{ + if (lamps!=NULL) + { + for (int i=0;i<num;i++) delete lamps[i]; + delete [] lamps; + lamps=NULL; + } +} + +void RhythmView::setRhythm(int numerator,int denominator) +{ + int i; + if (lamps!=NULL) + { + for (i=0;i<num;i++) delete lamps[i]; + delete [] lamps; + lamps=NULL; + } + num=numerator; + den=denominator; + + lamps=new KLed *[num]; + int w=width()/num; + int x=0; + + for (i=0;i<num;i++) + { + lamps[i]=new KLed(Qt::yellow, KLed::Off, KLed::Sunken, KLed::Rectangular, this); +// lamps[i]->setState(KLed::Off); + lamps[i]->setGeometry(x+2,0,w-4,height()); + lamps[i]->show(); + x+=w; + } +// lamps[0]->setState(KLed::On); + +} + +void RhythmView::Beat(int j) +{ + if (j>num) setRhythm(j,4); // This is a preventive case + + for (int i=0;i<num;i++) + { + lamps[i]->off(); + } + lamps[j-1]->on(); +} + +void RhythmView::Beat(void) +{ + +} + +void RhythmView::resizeEvent(QResizeEvent *) +{ + int w=width()/num; + int x=0; + + for (int i=0;i<num;i++) + { + lamps[i]->setGeometry(x+2,0,w-4,height()); + x+=w; + } +} + +QSize RhythmView::sizeHint() +{ + return QSize(10,10); +} + +QSizePolicy RhythmView::sizePolicy() +{ +// return QWidget::sizePolicy(); + return QSizePolicy(QSizePolicy::Expanding,QSizePolicy::Minimum); +} + diff --git a/kmid/rhythmview.h b/kmid/rhythmview.h new file mode 100644 index 00000000..80402fad --- /dev/null +++ b/kmid/rhythmview.h @@ -0,0 +1,54 @@ +/************************************************************************** + + rhythmview.h - The RhythmView widget + Copyright (C) 1998 Antonio Larrosa Jimenez + + 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. + + Send comments and bug fixes to larrosa@kde.org + or to Antonio Larrosa, Rio Arnoya, 10 5B, 29006 Malaga, Spain + +***************************************************************************/ +#ifndef _rhythmview_h_ +#define _rhythmview_h_ + +#include <qwidget.h> +#include <kled.h> + +class RhythmView : public QWidget +{ + int num,den; + + KLed **lamps; + +public: + RhythmView (QWidget *parent, const char *name); + ~RhythmView(); + + void setRhythm(int numerator,int denominator); + + void Beat(int i); // Sets the beat number + + void Beat(void); // Just increase the beat + + QSize sizeHint(); + QSizePolicy sizePolicy(); + +private: + void resizeEvent(QResizeEvent *); + +}; + +#endif diff --git a/kmid/slman.cpp b/kmid/slman.cpp new file mode 100644 index 00000000..62acdd2b --- /dev/null +++ b/kmid/slman.cpp @@ -0,0 +1,320 @@ +/************************************************************************** + + slman.cc - SongList Manager, which holds a set of collections (SongLists) + Copyright (C) 1997,98 Antonio Larrosa Jimenez + + 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. + + Send comments and bug fixes to larrosa@kde.org + or to Antonio Larrosa, Rio Arnoya, 10 5B, 29006 Malaga, Spain + +***************************************************************************/ +#include "slman.h" +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include "version.h" +#include <klocale.h> + +SLManager::SLManager() +{ + list=NULL; + ntotal=0; + tempsl=NULL; + createTemporaryCollection(); +} + +SLManager::SLManager(SLManager &src) +{ + list=NULL; + ntotal=0; + tempsl=NULL; + SongListNode *srcSL=src.list; + SongList *tmpSL; + int i; + while (srcSL!=NULL) + { + i=createCollection(srcSL->name); + tmpSL=getCollection(i); + if (tmpSL!=NULL) + tmpSL->copy(*srcSL->SL); + srcSL=srcSL->next; + } + if (src.tempsl!=NULL) tempsl=new SongList(*src.tempsl); + else tempsl=NULL; +} + +SLManager::~SLManager() +{ + SongListNode *ptr; + ptr=list; + while (ptr!=NULL) + { + list=ptr->next; + if (ptr->SL!=NULL) delete ptr->SL; + if (ptr->name!=NULL) delete ptr->name; + delete ptr; + ptr=list; + } + if (tempsl!=NULL) delete tempsl; + ntotal=0; +} + +int SLManager::createCollection(const char *name) +{ + SongListNode *ptr; + if (nameUsed(name)) + { + printf("Name '%s' is already used\n",name); + return -1; + } + if (list==NULL) + { + list=new SongListNode; + list->id=1; + ntotal=1; + ptr=list; + } + else + { + ptr=list; + while (ptr->next!=NULL) ptr=ptr->next; + ptr->next=new SongListNode; + ptr=ptr->next; + + ptr->id= ++ntotal; + } + ptr->SL=new SongList; + ptr->next=NULL; + if (name!=NULL) + { + ptr->name=new char[strlen(name)+1]; + strcpy(ptr->name,name); + } + else + { + ptr->name=getNotUsedName(); + } +return ptr->id; +} + +char *SLManager::getNotUsedName(void) +{ + char *trythis; + trythis=new char[100]; + strcpy(trythis,"No Name"); + int tries=1; + int success=0; + while (!success) + { + if (nameUsed(trythis)) sprintf(trythis,"No Name - %d",++tries); + else + success=1; + } + return trythis; +} + +int SLManager::nameUsed(const char *name) +{ + /* + SongListNode *ptr=list; + int used=0; + while ((!used)&&(ptr!=NULL)) + { + if (strcmp(ptr->name,name)==0) used=1; + ptr=ptr->next; + }; + return used; + */ + if (getCollection(name)==NULL) return 0; + return 1; +} + +void SLManager::deleteCollection(int id) +{ + if (list==NULL) return; + SongListNode *ptr=list; + SongListNode *ptr2; + if (id==1) list=list->next; + else + { + ptr2=list; + while ((ptr!=NULL)&&(ptr->id!=id)) + { + ptr2=ptr; + ptr=ptr->next; + } + if (ptr==NULL) + { + printf("Trying to delete a not used id\n"); + return; + } + ptr2->next=ptr->next; + } + ptr2=ptr->next; + delete ptr->SL; + delete ptr->name; + delete ptr; + regenerateid(ptr2,id); + +} + +void SLManager::regenerateid(SongListNode *sl,int id) +{ + SongListNode *tmp=sl; + int i=id; + while (tmp!=NULL) + { + tmp->id=i++; + tmp=tmp->next; + } + ntotal=i-1; +} + +void SLManager::changeCollectionName(int id,const char *newname) +{ + if (id<1) return; + if (nameUsed(newname)) + { + printf("Cannot change name, '%s' is already used\n",newname); + return; + } + SongListNode *ptr=list; + while ((ptr!=NULL)&&(ptr->id!=id)) ptr=ptr->next; + if (ptr==NULL) return; + + delete ptr->name; + ptr->name=new char[strlen(newname)+1]; + strcpy(ptr->name,newname); +} + +SongList *SLManager::getCollection(int id) +{ + if (id==0) return tempsl; + + SongListNode *ptr=list; + while ((ptr!=NULL)&&(ptr->id!=id)) ptr=ptr->next; + + if (ptr==NULL) return NULL; + return ptr->SL; +} + +SongList *SLManager::getCollection(const char *name) +{ + SongListNode *ptr=list; + while ((ptr!=NULL)&&(strcmp(ptr->name,name)!=0)) ptr=ptr->next; + + if (ptr==NULL) return NULL; + return ptr->SL; +} + +const char *SLManager::getCollectionName(int id) +{ + if (id==0) return I18N_NOOP("Temporary Collection"); + SongListNode *ptr=list; + while ((ptr!=NULL)&&(ptr->id!=id)) ptr=ptr->next; + + if (ptr==NULL) return NULL; + return ptr->name; +} + +void SLManager::loadConfig(const char *filename) +{ +#ifdef GENERAL_DEBUG_MESSAGES + printf("Loading collections\n"); +#endif + FILE *fh=fopen(filename,"rt"); + if (fh==NULL) + { + printf("Collections cannot be loaded\n(File %s doesn't exist or can't be opened)\n",filename); + return; + } + char s[300]; + SongList *sl=NULL; + int activeid=0; + while (!feof(fh)) + { + s[0] = 0; + fgets(s,299,fh); + if ((strlen(s)>0)&&(s[strlen(s)-1]==10)) s[strlen(s)-1]=0; + switch (s[0]) + { + case (0) : break; + case (10) : break; + case ('=') : + { + if (sl!=NULL) sl->setActiveSong(activeid); + int id=createCollection(&s[1]); + sl=getCollection(id); + fgets(s,299,fh); + activeid=atoi(s); + } + break; + default : + { + if (sl!=NULL) sl->AddSong((const char *)s); + } + } + } + if (sl!=NULL) sl->setActiveSong(activeid); + + fclose(fh); +} + +void SLManager::saveConfig(const char *filename) +{ + SongListNode *ptr=list; + FILE *fh=fopen(filename,"wt"); + if (fh==NULL) + { + printf("Collections couldn't be saved\n"); + return; + } + char s[FILENAME_MAX]; + SongList *sl; + while (ptr!=NULL) + { + sprintf(s,"=%s\n",ptr->name); + fputs(s,fh); + + sl=ptr->SL; + sprintf(s,"%d\n",sl->getActiveSongID()); + fputs(s,fh); + + sl->iteratorStart(); + while (!sl->iteratorAtEnd()) + { + sprintf(s,"%s\n",sl->getIteratorName()); + fputs(s,fh); + sl->iteratorNext(); + } + // ptr->SL->saveList(fh); + fputs("\n",fh); + + ptr=ptr->next; + } + fclose(fh); + +} + +SongList *SLManager::createTemporaryCollection(void) +{ + if (tempsl==NULL) + tempsl=new SongList(); + else + tempsl->clean(); + + return tempsl; +} diff --git a/kmid/slman.h b/kmid/slman.h new file mode 100644 index 00000000..3013f242 --- /dev/null +++ b/kmid/slman.h @@ -0,0 +1,74 @@ +/* slman.h - SongList Manager, which holds a set of collections (SongLists) + Copyright (C) 1997,98,99,2000 Antonio Larrosa Jimenez + + 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. + + Send comments and bug fixes to larrosa@kde.org + or to Antonio Larrosa, Rio Arnoya, 10 5B, 29006 Malaga, Spain + +***************************************************************************/ +#ifndef SLMAN_H +#define SLMAN_H + +#include "songlist.h" + +class SLManager +{ +protected: +int ntotal; + +struct SongListNode + { + int id; + char *name; + SongList *SL; + + SongListNode *next; + }; +SongListNode *list; +SongList *tempsl; + +char *getNotUsedName(void); +int nameUsed(const char *name); +void regenerateid(SongListNode *sl,int id); + +public: +SLManager(); +SLManager(SLManager &src); // Copy constructor +~SLManager(); + +int createCollection(const char *name=NULL); // Returns the id associated to the + // new collection + // -1 if name already is used and Collection was + // not created + +void deleteCollection(int id); +void changeCollectionName(int id, const char *newname); + +SongList *getCollection(int id); +SongList *getCollection(const char *name); +const char *getCollectionName(int id); + +int numberOfCollections(void) {return ntotal;}; + +void loadConfig(const char *filename); +void saveConfig(const char *filename); + +SongList *createTemporaryCollection(void); +SongList *getTemporaryCollection(void) {return tempsl;}; + +}; + +#endif diff --git a/kmid/songlist.cpp b/kmid/songlist.cpp new file mode 100644 index 00000000..8d98600c --- /dev/null +++ b/kmid/songlist.cpp @@ -0,0 +1,247 @@ +/************************************************************************** + + songlist.cc - class SongList, which holds a list of songs (collection) + Copyright (C) 1997,98 Antonio Larrosa Jimenez + + 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. + + Send comments and bug fixes to larrosa@kde.org + or to Antonio Larrosa, Rio Arnoya, 10 5B, 29006 Malaga, Spain + +***************************************************************************/ +#include "songlist.h" +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +SongList::SongList(void) +{ + list=NULL; + last=NULL; + active=NULL; + ntotal=0; +} + +SongList::SongList(SongList &src) +{ + list=last=active=NULL; + ntotal=0; + src.iteratorStart(); + while (!src.iteratorAtEnd()) + { + AddSong(src.getIteratorName()); + src.iteratorNext(); + } + if (src.active!=NULL) active=getSongid(src.active->id); +} + +SongList::~SongList() +{ + clean(); + Song *ptr=list; + active=last=NULL; + ntotal=0; + + while (ptr!=NULL) + { + list=ptr->next; + delete ptr->name; + delete ptr; + ptr=list; + } + +} + +SongList::Song *SongList::getSongid(int id) +{ + Song *ptr=list; + while ((ptr!=NULL)&&(ptr->id!=id)) + ptr=ptr->next; + + return ptr; +} + +int SongList::AddSong(const char *song) +{ + if (!song) return 0; + + if (last==NULL) + { + last=new Song; + list=last; + } + else + { + last->next=new Song; + last=last->next; + } + last->name=new char[strlen(song)+1]; + strcpy(last->name,song); + last->id= ++ntotal; + last->next=NULL; + if (active==NULL) active=last; + return last->id; +} + +void SongList::DelSong(int id) +{ + Song *ptr; + + if (list==NULL) return; + if (id==1) + { + if (last->id==1) + { + list=last=active=NULL; + ntotal=0; + } + else + { + ptr=list; + if (active->id==1) active=list->next; + list=list->next; + delete ptr->name; + delete ptr; + ntotal--; + + regenerateid(list,1); + } + return; + } + Song *ptr_prev=getSongid(id-1); + ptr=ptr_prev->next; + if (last->id==id) last=ptr_prev; + if (active->id==id) + if (active->next!=NULL) active=active->next; + else active=ptr_prev; + + ntotal--; + ptr_prev->next=ptr->next; + delete ptr->name; + delete ptr; + regenerateid(ptr_prev->next,id); + +} + +void SongList::regenerateid(Song *song,int id) +{ + Song *tmp=song; + int i=id; + while (tmp!=NULL) + { + tmp->id=i++; + tmp=tmp->next; + } + ntotal=i-1; +} + +void SongList::setActiveSong(int id) +{ + Song *tmp=getSongid(id); + if (tmp!=NULL) active=tmp; +} + +char *SongList::getName(int id) +{ + Song *tmp=getSongid(id); + if (tmp!=NULL) return tmp->name; + return NULL; +} + +/* +void SongList::saveList(FILE *fh) +{ + Song *ptr=list; + while (ptr!=NULL) + { + fputs(fh,ptr->name); + ptr=ptr->next; + } +} +*/ + +void SongList::iteratorStart(void) +{ + it=list; +} + +void SongList::iteratorNext(void) +{ + if (it!=NULL) it=it->next; +} + +int SongList::getIteratorID(void) +{ + if (it==NULL) return -1; + return it->id; +} + +char *SongList::getIteratorName(void) +{ + if (it==NULL) return NULL; + return it->name; +} + + +void SongList::clean(void) +{ + Song *tmp=list; + active=last=NULL; + ntotal=0; + + while (tmp!=NULL) + { + list=tmp->next; + delete [] tmp->name; + delete tmp; + tmp=list; + } +} + +void SongList::copy(SongList &src) +{ + clean(); + src.iteratorStart(); + while (!src.iteratorAtEnd()) + { + AddSong(src.getIteratorName()); + src.iteratorNext(); + } + if (src.active!=NULL) active=getSongid(src.active->id); +} + +int SongList::next(void) +{ + if (list==NULL) {active=NULL;return 0;}; + if (active!=NULL) active=active->next; + if (active==NULL) + { + Song *tmp=list; + while (tmp->next!=NULL) tmp=tmp->next; + active=tmp; + return 0; + } + return 1; +} + + +void SongList::previous(void) +{ + if (list==NULL) {active=NULL;return;}; + Song *tmp=list; + while ((tmp->next!=NULL)&&(tmp->next->id!=active->id)) tmp=tmp->next; + if (tmp->next==NULL) {active=list;return;}; + active=tmp; +} diff --git a/kmid/songlist.h b/kmid/songlist.h new file mode 100644 index 00000000..85203c46 --- /dev/null +++ b/kmid/songlist.h @@ -0,0 +1,84 @@ +/* songlist.h - class SongList, which holds a list of songs (collection) + Copyright (C) 1997,98,99,2000 Antonio Larrosa Jimenez + + 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. + + Send comments and bug fixes to larrosa@kde.org + or to Antonio Larrosa, Rio Arnoya, 10 5B, 29006 Malaga, Spain + +***************************************************************************/ +#ifndef SONGLIST_H +#define SONGLIST_H + +#include <stdio.h> + +class SongList +{ +protected: +int ntotal; + +struct Song +{ + int id; + char *name; // complete path and file name + + Song *next; +}; + +Song *list; +Song *last; +Song *active; + +Song *it; // Iterator, just a helper variable to make easy (and fast) reading + // all the list + +Song *getSongid(int id); + +void regenerateid(Song *song,int id); + +public: +SongList(void); +SongList(SongList &src); // Copy constructor +~SongList(); + +int AddSong(const char *song); // Returns the id number assigned to the song +void DelSong(int id); + +int NumberOfSongs(void) { return ntotal; }; + +void setActiveSong(int id); +int getActiveSongID(void) {return ((active!=NULL)? (active->id ):(-1)); }; +char *getActiveSongName(void) + { + return ((active!=NULL)? (active->name):((char *)NULL)); + }; + +char *getName(int id); // Returns the name of the song with id id + +void previous(void); +int next(void); // returns 1 if evrything is ok, and 0 if it was the last element + // (but leaves active the last element instead of NULL) + +void iteratorStart(void); +void iteratorNext(void); +int iteratorAtEnd (void) {return (it==NULL);}; +int getIteratorID(void); +char *getIteratorName(void); + +void clean(void); // Clean this list +void copy(SongList &src); // Makes this object a copy of src (really copied) +}; + +#endif diff --git a/kmid/std.o3 b/kmid/std.o3 Binary files differnew file mode 100644 index 00000000..e58311da --- /dev/null +++ b/kmid/std.o3 diff --git a/kmid/std.sb b/kmid/std.sb Binary files differnew file mode 100644 index 00000000..4fe2d0be --- /dev/null +++ b/kmid/std.sb diff --git a/kmid/version.h b/kmid/version.h new file mode 100644 index 00000000..be282fff --- /dev/null +++ b/kmid/version.h @@ -0,0 +1,48 @@ +#ifndef _VERSION_H + + +#define VERSION_NUM 2.0 +#define VERSION_SHORTTXT "2.0" +#define VERSION_TXT "KMid 2.0" + +// Undefine WORKING for release versions +//#define WORKING + +// I want to keep some special variables defined at home for personal +// adjustments +//#define AT_HOME + + +// The next definition makes kmid display some general debug messages +// that may be helpful to locate any bug, but without making lots of +// messages. Please when reporting a bug, be sure that this is set and +// send me the output. +//#define GENERAL_DEBUG_MESSAGES + +// Define MODE_DEMO_ONLYVISUAL for kmid to work on systems with no soundcard, +// or when it is not well configured. You will only get visual feedback, that +// is, you will see the letter changing of colors, but no music. Really, you +// would get music if it is possible, but by defining this, many synchronization +// routines will be turned off. +//#define MODE_DEMO_ONLYVISUAL + + +// And now, DEBUG messages : +#ifdef WORKING +#define KMidDEBUG +//#define KDISPTEXTDEBUG +//#define COLLECTDLGDEBUG +//#define DEVICEMANDEBUG +//#define FMOUTDEBUG +//#define GUSOUTDEBUG +//#define MIDFILEDEBUG +//#define MIDIOUTDEBUG +//#define MIDISTATDEBUG +//#define MIDIMAPPERDEBUG +//#define SYNTHOUTDEBUG +//#define VOICEMANDEBUG +//#define PLAYERDEBUG +//#define TRACKDEBUG +#endif + +#endif diff --git a/kmid/x-karaoke.desktop b/kmid/x-karaoke.desktop new file mode 100644 index 00000000..2784f27a --- /dev/null +++ b/kmid/x-karaoke.desktop @@ -0,0 +1,61 @@ +[Desktop Entry] +Type=MimeType +MimeType=audio/x-karaoke +Icon=sound +Patterns=*.kar;*.KAR; +Comment=Karaoke File +Comment[ar]=ملف Karaoke +Comment[bg]=Файл на Karaoke +Comment[bn]=কারাওকে ফাইল +Comment[br]=Restr Karaoke +Comment[bs]=Karaoke datoteka +Comment[ca]=Fitxer karaoke +Comment[cs]=Karaoke soubor +Comment[cy]=Ffeil Karaoke +Comment[da]=Karaoke-fil +Comment[de]=Karaoke-Datei +Comment[el]=Αρχείο Karaoke +Comment[eo]=Karaoko-dosiero +Comment[es]=Archivo Karaoke +Comment[et]=Karaoke fail +Comment[eu]=Karaoke fitxategia +Comment[fa]=پروندۀ Karaoke +Comment[fi]=Karaoketiedosto +Comment[fr]=Fichier de karaoké +Comment[ga]=Comhad Karaoke +Comment[gl]=Ficheiro Karaoke +Comment[he]=קובץ קריוקי +Comment[hi]=कराओके फ़ाइल +Comment[hu]=Karaoke-fájl +Comment[is]=Karaoke skrá +Comment[ja]=カラオケファイル +Comment[kk]=Караоке файлы +Comment[km]=ឯកសារខារ៉ាអូខេ +Comment[ko]=노래방 파일 +Comment[lt]=Karaoke byla +Comment[mk]=Karaoke датотека +Comment[nb]=Karaokefil +Comment[nds]=Karaoke-Datei +Comment[ne]=कारावके फाइल +Comment[nl]=Karaoke-bestand +Comment[nn]=Karaokefil +Comment[pl]=Plik Karaoke +Comment[pt]=Ficheiro de Karaoke +Comment[pt_BR]=Arquivo Karaokê +Comment[ro]=Fişier karaoke +Comment[ru]=Файл караоке +Comment[sk]=Karaoke súbor +Comment[sl]=Datoteka Karaoke +Comment[sr]=Караоке фајл +Comment[sr@Latn]=Karaoke fajl +Comment[sv]=Karaoke-fil +Comment[ta]=கரோக்கி கோப்பு +Comment[tg]=Файли Karaoke +Comment[th]=แฟ้มคาราโอเกะ +Comment[tr]=Karaoke Dosyası +Comment[uk]=Файл Karaoke +Comment[uz]=Karaoki fayli +Comment[uz@cyrillic]=Караоки файли +Comment[zh_CN]=卡拉 OK 文件 +Comment[zh_HK]=卡拉OK 檔案 +Comment[zh_TW]=卡拉OK檔案 |