radiostation.cpp

Go to the documentation of this file.
00001 /*
00002     Copyright (C) 2008  Tim Fechtner < urwald at users dot sourceforge dot net >
00003 
00004     This program is free software; you can redistribute it and/or
00005     modify it under the terms of the GNU General Public License as
00006     published by the Free Software Foundation; either version 2 of
00007     the License or (at your option) version 3 or any later version
00008     accepted by the membership of KDE e.V. (or its successor approved
00009     by the membership of KDE e.V.), which shall act as a proxy
00010     defined in Section 14 of version 3 of the license.
00011 
00012     This program is distributed in the hope that it will be useful,
00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015     GNU General Public License for more details.
00016 
00017     You should have received a copy of the GNU General Public License
00018     along with this program.  If not, see <http://www.gnu.org/licenses/>.
00019 */
00020 
00021 #include "radiostation.h"
00022 
00023 #include <KStandardDirs>
00024 #include <KConfig>
00025 #include <KTemporaryFile>
00026 
00027 #define AND  &&
00028 #define OR  ||
00029 #define NOT  !
00030 #define EQUAL  ==
00031 
00032 radioStation::radioStation(const QPointer<QObject> parent,
00033                             const QPointer<QWidget> mainWidget,
00034                             const QString &configFileName) : ripping(parent)
00035 {
00036   m_mainWidget = mainWidget;
00037   helper_setupConfigSystem(configFileName);
00038 }
00039 
00040 radioStation::radioStation(const QPointer<QObject> parent,
00041                             const QPointer<QWidget> mainWidget,
00042                             const QString &configFileName,
00043                             const qlonglong &index) : ripping(parent)
00044 {
00045   setIndex(index);
00046   m_mainWidget = mainWidget;
00047   helper_setupConfigSystem(configFileName);
00048 }
00049 
00050 radioStation::~radioStation()
00051 {
00052   delete config_skeleton;  /*  We have to delete the object on which config_skeleton
00053     points to - _befor_ deleting the object shared_config points on because the first
00054     makes use of the second. As the object shared_config points on is deleted when it's
00055     pointer (shared_config is a special pointer managing this) is deleted (and that's
00056     done - as the pointer is a member of this class - after the descturctor call) we
00057     can make sure by deleting config_skeleton explicitly here that the object config_skeleton
00058     points on is deleted _befor_ the object shared_config points on. I don't want to
00059     relay on the QObject-parentship-system because I don't know _when_ exactly the child
00060     object is deleted, and this way it is sure. */
00061   delete settingsDialog;  /* Maybe there exists still a settingsDialog. (Because settingsDialog
00062     deletes itself after closing, this is only the case if the settingsDialog is still open.)
00063     Because the parent isn't this object, but m_mainWidget, the settingsDialog will not be
00064     automatically deleted by Qt and we have to do it manually. */
00065 }
00066 
00067 inline void radioStation::helper_setupConfigSystem(const QString & configFileName)
00068 {
00069   // variables
00070   QFile file;
00071 
00072   /* make sure that internal_configFileName contains the path of a file which is
00073   *  readable and writeable. If possible, using "configFile" option passed to the
00074   *  contructor. If not, create a new (empty) one. */
00075   file.setFileName(configFileName);
00076   // TODO: catch error message if file name is empty!
00077   // TODO: replace the following block with code, that doesn't open the file,
00078   // but only collects information
00079   //       if the files are acessible.
00080   if (file.open(QIODevice::ReadWrite)) { // file (which was passed through
00081     // "configFileName" option in the constructor) working fine. Use it.
00082     file.close();
00083     internal_configFileName = configFileName;
00084   } else {                                   // create a new file
00085     KTemporaryFile newConfigFile;
00086     newConfigFile.setPrefix(KStandardDirs::locateLocal("appdata", "stream_")); // TODO warum
00087     // nicht locate() ?
00088     newConfigFile.setSuffix("_rc");
00089     if (!newConfigFile.open()) {
00090       // TODO handle error...
00091     }
00092     newConfigFile.setAutoRemove(false);
00093     internal_configFileName = newConfigFile.fileName();
00094     newConfigFile.close();
00095   };
00096 
00097   // setup configuration system
00098   shared_config = KSharedConfig::openConfig(internal_configFileName, KConfig::SimpleConfig);
00099   // We don't use a full-featured config system (with kiosk system and system-wide settings),
00100   // but we only read our streamConfig file.
00101   config_skeleton = new settings_stream(shared_config); // no constructor where I
00102   // can pass a parent
00103   /* config_skeleton->setParent(this) would also be a bad idea;
00104   So here I don't use QObject's parent-child-system but delete
00105   the object in the destructor. See there for further explications. */
00106 }
00107 
00108 QString radioStation::configFileName() const
00109 {
00110   return internal_configFileName;
00111 }
00112 
00113 PropertyValue radioStation::streamName() const
00114 {
00115   return formatedStreamName(config_skeleton->info_streamName());
00116 }
00117 
00118 void radioStation::setStreamName(const QString streamName)
00119 {
00120   if (config_skeleton->info_streamName() != streamName) {
00121     config_skeleton->setInfo_streamName(streamName);
00122     config_skeleton->writeConfig();
00123     ripping::setStreamName(streamName);
00124   };
00125 }
00126 
00127 PropertyValue radioStation::serverName() const
00128 {
00129   return formatedServerName(config_skeleton->info_serverName());
00130 }
00131 
00132 void radioStation::setServerName(const QString serverName)
00133 {
00134   if (config_skeleton->info_serverName() != serverName) {
00135     config_skeleton->setInfo_serverName(serverName);
00136     config_skeleton->writeConfig();
00137     ripping::setServerName(serverName);
00138   };
00139 }
00140 
00141 PropertyValue radioStation::bitrate() const
00142 {
00143   return formatedBitrate(config_skeleton->info_bitrate());
00144 }
00145 
00146 void radioStation::setBitrate(qint64 bitrate)
00147 {
00148   // config_skeleton makes sure that no invalid value is stored
00149   if (config_skeleton->info_bitrate() != bitrate) {
00150     config_skeleton->setInfo_bitrate(bitrate);
00151     config_skeleton->writeConfig();
00152     ripping::setBitrate(bitrate);
00153   };
00154 }
00155 
00156 PropertyValue radioStation::metaInterval() const
00157 {
00158   return formatedMetaInterval(config_skeleton->info_metaInterval());
00159 }
00160 
00161 void radioStation::setMetaInterval(qint64 metaInterval)
00162 {
00163   // config_skeleton makes sure that no value < -1 is stored...
00164   if (config_skeleton->info_metaInterval() != metaInterval) {
00165     config_skeleton->setInfo_metaInterval(metaInterval);
00166     config_skeleton->writeConfig();
00167     ripping::setMetaInterval(metaInterval);
00168   };
00169 }
00170 
00171 QString radioStation::serverUri() const
00172 {
00173   return config_skeleton->serverUri();
00174 }
00175 
00176 QStringList radioStation::parameterList() const
00177 {
00178   // variables
00179   QStringList parameters;
00180 
00181   //code
00182   //TODO: options who aren't in the kcfg's
00183   // calculate all parameters
00184   parameters += ripping::parameterList();
00185 
00186   parameters.append(QString("-u"));
00187   parameters.append(config_skeleton->advanced_userAgentString());  //TODO test if this
00188   // works when the string is empty
00189 
00190   parameters.append(QString("--xs_offset=%1").
00191                      arg(config_skeleton->offset()));
00192 
00193   /* The following code produces a search window which length corresponds exactly
00194   to the value in the settings. When the value is odd, the last half of the window
00195   is 1 ms longer. */
00196   parameters.append(QString("--xs_search_window=%1:%2").
00197                      arg(config_skeleton->searchWindow() / 2).
00198                      arg((config_skeleton->searchWindow() / 2) +
00199                           (config_skeleton->searchWindow() % 2)));
00200 
00201   parameters.append(QString("--xs_silence_length=%1").
00202                      arg(config_skeleton->silenceWindow()));
00203 
00204   if (config_skeleton->writeSingleFile()) {
00205     parameters.append(QString("-a"));    //TODO file name schemes for single files: append here
00206   };
00207 
00208   if (config_skeleton->writeSplittedFiles()) {
00209     //TODO file name schemes splitted files
00210     parameters.append(QString("--xs_padding=%1:%2").
00211                        arg(config_skeleton->splittedFilesPostpad()).
00212                        arg(config_skeleton->splittedFilesPrepad()));
00213   } else {
00214     parameters.append(QString("-A"));
00215   };
00216 
00217   parameters.append(QString("-k"));
00218   parameters.append(QString::number(config_skeleton->skipFirstXTracks()));
00219 
00220   if (config_skeleton->advanced_useTimeout()) {
00221     parameters.append(QString("-m"));
00222     parameters.append(QString::number(config_skeleton->advanced_timeoutAfterXSeconds()));
00223   }
00224 
00225   if (config_skeleton->truncateDuplicatesInIncomplete()) {
00226     parameters.append(QString("-T"));
00227   };
00228 
00229   return parameters;
00230 }
00231 
00232 int radioStation::helper_displaySettingsDialog(bool returnImmediately)
00233 {
00234   // variables
00235   int exitCode;
00236 
00237   // code
00238   /* If the dialog object yet exists, we can display it directly and return.
00239   (Should normally not happen, because we delete it after the use. And the dialog
00240   is modal, so the user can't open a second dialog. We do this here just to be
00241   absolutly sure.) We are using name of the config file as name of the dialog because
00242   this name is unique! */
00243   if (settingsDialog.isNull()) {
00244     settingsDialog = new settings_stream_dialog(m_mainWidget,
00245                                                  internal_configFileName,
00246                                                  config_skeleton);
00247     connect(settingsDialog,
00248              SIGNAL(finished()),
00249              settingsDialog,
00250              SLOT(deleteLater()));
00251   };
00252   if (returnImmediately) {
00253     settingsDialog->show();
00254     exitCode = KDialog::Accepted;
00255   } else {
00256     exitCode = settingsDialog->exec();
00257   };
00258   return exitCode;
00259 }
00260 
00261 void radioStation::showSettingsDialog()
00262 {
00263   helper_displaySettingsDialog(true);
00264 }
00265 
00266 int radioStation::execSettingsDialog()
00267 {
00268   return helper_displaySettingsDialog(false);
00269 }

Generated on Sat May 2 10:43:44 2009 for kradioripper by  doxygen 1.5.6