Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members

bluephone.cpp

00001 /*! 00002 @class BluePhone 00003 @brief Hauptklasse von BluePhone. 00004 @author Thomas Gemperli, <bluephone@gemperli.net> 00005 @version 1.0 00006 @date 2004-08-03 00007 @par This program is free software; you can redistribute it and/or 00008 modify it under the terms of the GNU General Public License. 00009 @file bluephone.cpp 00010 */ 00011 00012 00013 #include "bluephone.h" 00014 00015 #include <qlineedit.h> 00016 #include <qprogressbar.h> 00017 #include <qradiobutton.h> 00018 #include <qspinbox.h> 00019 #include <qmessagebox.h> 00020 #include <qlistview.h> 00021 #include <qtabwidget.h> 00022 #include <qfiledialog.h> 00023 #include <kled.h> 00024 #include <kfileitem.h> 00025 #include <fstream> 00026 #include <unistd.h> 00027 00028 00029 00030 /** 00031 * BluePhone Konstruktor 00032 * Erstellt das QWidget Objekt BluePhone im Hauptfenster. 00033 */ 00034 BluePhone::BluePhone(QWidget* parent, const char* name, WFlags fl) 00035 : FormBluePhone(parent,name,fl) 00036 { 00037 00038 /* Initialisierungen. */ 00039 version = "1.0"; 00040 00041 /* Zeiger auf NULL */ 00042 m_Port = NULL; 00043 00044 /* Diese Devices sind korrekt fuer Linux 2.4 TODO: devfs */ 00045 m_defaultBtDevice="/dev/rfcomm0"; 00046 m_defaultIrdaDevice="/dev/ircomm0"; 00047 m_defaultSerialDevice="/dev/ttyS0"; 00048 00049 00050 /* Lese die Konfiguration aus dem Configfile ein. */ 00051 readSettings(); 00052 00053 /* Spitze die Config in das Settings Tab ab. */ 00054 setSettingsView(); 00055 00056 /* Verbinde automatisch mit Telephon, wenn das Flag in der Config gesetzt ist.*/ 00057 if (m_ConnectStartup == "Yes") 00058 { 00059 phoneConnect(); 00060 } 00061 else 00062 { 00063 phoneGetInfo(); 00064 } 00065 00066 /* Vestecke die ID Spalte der SMS Ansicht. BluePhone braucht diese Info, der Benutzer nicht. */ 00067 //DOESNOTWORK 00068 //listViewSms->hideColumn(0); 00069 00070 /* Vestecke die ID Spalte der Kontakte Ansicht. BluePhone braucht diese Info, der Benutzer nicht. */ 00071 //DOESNOTWORK 00072 //listViewContacts->hideColumn(0); 00073 00074 } 00075 00076 00077 /** 00078 * BluePhone Destruktor 00079 */ 00080 BluePhone::~BluePhone() 00081 { 00082 } 00083 00084 00085 00086 /** 00087 * Diese Methode liest, falls vorhanden, die aktuellen Settings aus dem Configfile ein. 00088 */ 00089 void BluePhone::readSettings() 00090 { 00091 /* Erstelle BlueSettings Objekt */ 00092 BlueSettings mySettings; 00093 00094 /* Setzen der Werte */ 00095 m_settingsAll = mySettings.readSettings(); 00096 00097 m_Device = m_settingsAll.section(',',0,0); 00098 m_BtAddress = m_settingsAll.section(',',1,1); 00099 m_BtChannel = m_settingsAll.section(',',2,2); 00100 m_ConnectStartup = m_settingsAll.section(',',3,3); 00101 } 00102 00103 00104 /** 00105 * Diese Methode fuellt die Settings Form mit aktuellen Werten ab. 00106 */ 00107 void BluePhone::setSettingsView() 00108 { 00109 if (m_Device == m_defaultBtDevice) 00110 { 00111 radioButtonSettingsBluetooth->toggle(); 00112 } 00113 else if (m_Device == m_defaultIrdaDevice) 00114 { 00115 radioButtonSettingsIrDA->toggle(); 00116 } 00117 else if (m_Device == m_defaultSerialDevice) 00118 { 00119 radioButtonSettingsSerial->toggle(); 00120 } 00121 00122 if (m_ConnectStartup == "Yes") 00123 { 00124 radioButtonSettingsYes->toggle(); 00125 } 00126 else if (m_ConnectStartup == "No") 00127 { 00128 radioButtonSettingsNo->toggle(); 00129 } 00130 00131 lineEditSettingsAddress->setText(m_BtAddress); 00132 00133 m_BtChannelInt = m_BtChannel.toInt(); 00134 spinBoxSettingsPort->setValue(m_BtChannelInt); 00135 } 00136 00137 00138 /** 00139 * Diese Methode liest Informationen ueber eine File aus 00140 * und stellt diese im Tab "File" dar. 00141 * Parameter: QString "Pfad zur Datei" 00142 */ 00143 void BluePhone::showMetaInfo(const QString& pathToFile) 00144 { 00145 /* Erstelle ein "KFileItem" Objekt */ 00146 KFileItem myFileInfo(KFileItem::Unknown, KFileItem::Unknown, pathToFile, false); 00147 00148 /* Ist die Datei lesbar? */ 00149 if(myFileInfo.isReadable() && myFileInfo.isFile()) 00150 { 00151 /* Ermittle den Mime Type der Datei */ 00152 if(myFileInfo.isMimeTypeKnown()) 00153 { 00154 lineEditFileType->setText(myFileInfo.mimeComment()); 00155 } 00156 else 00157 { 00158 lineEditFileType->setText("Unknown"); 00159 } 00160 00161 /* Ermittle die Groesse der Datei */ 00162 lineEditFileSize->setText(KIO::convertSize(myFileInfo.size())); 00163 00164 /* Ermittle Metainformationen der Datei */ 00165 const KFileMetaInfo info = myFileInfo.metaInfo(); 00166 if(info.isValid()) 00167 { 00168 const KFileMetaInfoItem sizeInfo = info.item(KFileMimeTypeInfo::Size); 00169 00170 lineEditFileDimensions->setText(sizeInfo.string()); 00171 } 00172 else 00173 { 00174 lineEditFileDimensions->setText("---"); 00175 } 00176 00177 } 00178 else 00179 { 00180 00181 /* Loesche den Inhalt der Felder */ 00182 lineEditFileType->clear(); 00183 lineEditFileSize->clear(); 00184 lineEditFileDimensions->clear(); 00185 } 00186 } 00187 00188 00189 /** 00190 * Dieser Slot speichert die Settings. 00191 * Die Configuration wird in ~/.kde/share/config/bluephonerc gesichert 00192 */ 00193 void BluePhone::settingsSave() 00194 { 00195 /* Frage die Werte aus der Maske ab */ 00196 if (radioButtonSettingsBluetooth->isChecked()) 00197 { 00198 m_settingsDevice = m_defaultBtDevice; 00199 } 00200 else if (radioButtonSettingsIrDA->isChecked()) 00201 { 00202 m_settingsDevice = m_defaultIrdaDevice; 00203 } 00204 else if (radioButtonSettingsSerial->isChecked()) 00205 { 00206 m_settingsDevice = m_defaultSerialDevice; 00207 } 00208 00209 if (radioButtonSettingsYes->isChecked()) 00210 { 00211 m_settingsConnectStartup = "Yes"; 00212 } 00213 else if (radioButtonSettingsNo->isChecked()) 00214 { 00215 m_settingsConnectStartup = "No"; 00216 } 00217 00218 m_settingsBtAddress = lineEditSettingsAddress->text(); 00219 m_settingsBtChannel = spinBoxSettingsPort->value(); 00220 00221 00222 /* Falls wir noch mit dem Telephon verbunden sind, nun trennen. */ 00223 if (myLink.getState()) 00224 { 00225 phoneDisconnect(); 00226 } 00227 00228 /* Erstelle BlueSettings Objekt. */ 00229 BlueSettings mySettings; 00230 00231 /* Speichere die Settings. */ 00232 mySettings.writeSettings(m_settingsDevice, m_settingsBtAddress, m_settingsBtChannel, m_settingsConnectStartup); 00233 00234 /* Lese die Settings gleich ein. */ 00235 readSettings(); 00236 00237 QMessageBox::information( this, 00238 tr("Information"), 00239 tr("Config saved.\nNow connect your phone." ) 00240 ); 00241 } 00242 00243 00244 /** 00245 * Dieser Slot zeigt eine Messagebox an, die erklaert, wie die Bluetooth Adresse des Telephons gefunden werden kann. 00246 */ 00247 void BluePhone::settingsGetAddress() 00248 { 00249 QMessageBox::information( this, 00250 tr("How to get the BTADR"), 00251 tr("How to get the bluetooth address of your phone\n\n\n" 00252 "Open a Unix Shell and type in the following comand:\n\n" 00253 "hcitool scan\n\n" 00254 "The output of this comand will show you the bluetooth address and the name of your phone.\n" 00255 "A bluetooth address looks like this: 00:0A:D9:F7:3C:B6\n\n" 00256 "You can use copy & paste to put this value in the \"Bluetooth Address\" field.") 00257 ); 00258 } 00259 00260 00261 /** 00262 * Dieser Slot erstellt ein neues SMS an den selektierten Kontakt. 00263 */ 00264 void BluePhone::contactsSms() 00265 { 00266 if (myLink.getState()) 00267 { 00268 /* liefert das selektierte Item aus listViewContacts zurueck */ 00269 QListViewItem *selectedContact = listViewContacts->selectedItem(); 00270 00271 /* selectedItem liefert 0 zurueck, falls keine Selektion besteht */ 00272 if (selectedContact != 0) 00273 { 00274 /* Inhalt von listViewContacts (die Nummer) in die private Variable abspeichern. */ 00275 m_phoneSmsNumber = selectedContact->text(3); 00276 00277 /* Erstelle einen NewSms Dialog, teile ihm mit, dass dies eine neue Nachricht mit definiertem 00278 Empfaenger ist (fromcontact) und uebergebe den Empfaenger als weiteren Parameter an den Konstruktor. */ 00279 NewSms *myNewSmsDlg = new NewSms(this, 0, false, 0, "fromcontact", m_phoneSmsNumber); 00280 00281 /* Erstelle eine Signal-Slot Verbindung 00282 von: myNewSmsDlg::transmitSms (Quelle rsp. Signal) 00283 zu: this::sendSmsToPhone (this = BluePhone, Senke rsp. Slot) 00284 Es werden die folgenden Parameter uebermittelt: QString Receiver, QString Message, int index, int id */ 00285 QObject::connect( 00286 myNewSmsDlg, SIGNAL(transmitSms(const QString&, const QString&, int, int)), 00287 this, SLOT(sendSmsToPhone(const QString&, const QString&, int, int)) 00288 ); 00289 00290 /* Erstelle eine Signal-Slot Verbindung fuer die gruene LED Status Anzeige. */ 00291 QObject::connect( 00292 myNewSmsDlg, SIGNAL(transmitLedStateGreen()), 00293 this, SLOT(setLedGreen()) 00294 ); 00295 00296 /* Setzte die gelbe LED. Dies muss leider hier geschehen, ein Aufruf vom "Send" Button des myNewSmsDlg 00297 her kommt zu spaet, da der Fensterinhalt des Hauptfensters wird erst nach schliessen des Dialoges 00298 neu gezeichnet wird. */ 00299 setLedOrange(); 00300 00301 /* Zeige den NewSms Dialog an */ 00302 myNewSmsDlg->show(); 00303 } 00304 else 00305 { 00306 QMessageBox::information( this, 00307 tr("Information"), 00308 tr("Please select a Contact") 00309 ); 00310 } 00311 00312 setLedGreen(); 00313 } 00314 else 00315 { 00316 QMessageBox::warning( this, 00317 tr("Warning"), 00318 tr("Phone is not connected") 00319 ); 00320 } 00321 } 00322 00323 00324 /** 00325 * Dieser Slot ruft den selektierten Kontakt an. 00326 */ 00327 void BluePhone::contactsCall() 00328 { 00329 if (myLink.getState()) 00330 { 00331 /* liefert das selektierte Item aus listViewContacts zurueck */ 00332 QListViewItem *selectedContact = listViewContacts->selectedItem(); 00333 00334 /* selectedItem liefert 0 zurueck, falls keine Selektion besteht */ 00335 if (selectedContact != 0) 00336 { 00337 /* setze das AT Kommando fuer Call zuasammen */ 00338 m_AtCommand = "at*evd=\""; 00339 m_AtCommand.append(selectedContact->text(3)); 00340 m_AtCommand.append("\"\r"); 00341 00342 myLink.talktoPhone(m_Port, m_AtCommand); 00343 } 00344 else 00345 { 00346 QMessageBox::information( this, 00347 tr("Information"), 00348 tr("Please select a contact") 00349 ); 00350 } 00351 00352 setLedGreen(); 00353 } 00354 else 00355 { 00356 QMessageBox::warning( this, 00357 tr("Warning"), 00358 tr("Phone is not connected") 00359 ); 00360 } 00361 } 00362 00363 00364 /** 00365 * Dieser Slot ueberschreibt das Telephonbuch auf dem Telephon mit einem Backup. 00366 */ 00367 void BluePhone::contactsRestore() 00368 { 00369 if (myLink.getState()) 00370 { 00371 /* "Leere listViewContacts */ 00372 listViewContacts->clear(); 00373 00374 /* "Open File" Dialog */ 00375 m_FileName = QFileDialog::getOpenFileName( 00376 tr("/home"), 00377 tr("Text files (*.txt);;All files (*.*)"), 00378 this, 00379 tr("Open File"), 00380 tr("Open Backup") 00381 ); 00382 00383 /* User abfragen, ob er wirklich restoren will */ 00384 bool MessageboxAnswer = QMessageBox::question( this, 00385 tr("Question"), 00386 tr("Do you really want to restore your phonebook from %1 ?\n" 00387 "This will overwrite all contact entries on your phone!") 00388 .arg( m_FileName ), 00389 tr("&No"), tr("&Yes"), 00390 QString::null, 1, 0 ); 00391 00392 /* Hat der User ein File gewaehlt oder Cancel gedrueckt und will er wirklich? */ 00393 if (m_FileName && MessageboxAnswer) 00394 { 00395 /* was aus der guten, alten 3. Semester Zeit. Oeffne einen ifstream */ 00396 std::ifstream inputFile(m_FileName.latin1()); 00397 00398 /* 255 Bytes grossen Char Array erstellen. Brauchen wir fuer getline. */ 00399 char buffer[255]; 00400 00401 /* lese das Backup File bis zum EOF (EndOfFile) ein und spitze die Eintraege in listViewContacts ab */ 00402 while (!inputFile.eof()) 00403 { 00404 /* Hole eine Zeile */ 00405 inputFile.getline(buffer, 255); 00406 m_phoneContactEntry.setLatin1(buffer); 00407 00408 /* Ermittle die einzeln Werte des Eintrages*/ 00409 m_phoneContactId = m_phoneContactEntry.section(':',0,0); 00410 00411 m_phoneContactType = m_phoneContactEntry.section(':',1,1); 00412 if ( m_phoneContactType == "Home" ) 00413 { m_phoneContactType = "H"; } 00414 else if ( m_phoneContactType == "Work" ) 00415 { m_phoneContactType = "W"; } 00416 else if ( m_phoneContactType == "Mobile" ) 00417 { m_phoneContactType = "M"; } 00418 else if ( m_phoneContactType == "Fax" ) 00419 { m_phoneContactType = "F"; } 00420 else 00421 { m_phoneContactType = "O"; } 00422 00423 m_phoneContactName = m_phoneContactEntry.section(':',2,2); 00424 m_phoneContactNumber = m_phoneContactEntry.section(':',3,3); 00425 00426 /* Der Zeichensatz von m_phoneContactName muss noch fuer das Telephon umgewandelt werden*/ 00427 m_phoneContactName = myConvert.convert_to_gsm(m_phoneContactName); 00428 00429 /* setze das AT Kommando fuer das Telephon zusammen. Siehe AT Referenz. */ 00430 m_AtCommand = "at+cpbw="; 00431 m_AtCommand.append(m_phoneContactId); 00432 m_AtCommand.append(",\""); 00433 m_AtCommand.append(m_phoneContactNumber); 00434 m_AtCommand.append("\",,\""); 00435 m_AtCommand.append(m_phoneContactName); 00436 m_AtCommand.append("/"); 00437 m_AtCommand.append(m_phoneContactType); 00438 m_AtCommand.append("\"\r"); 00439 00440 /* uebermittle dem Telephon den Telephonbuch Eintrag */ 00441 myLink.talktoPhone(m_Port, m_AtCommand); 00442 00443 /* Sortiere die Eintraege dem Namen nach */ 00444 listViewContacts->setSorting(2); 00445 listViewContacts->sort(); 00446 } 00447 00448 /* Lese das Telephonbuch vom Telephon ein. So kann der User ueberpruefen, ob alles geklappt hat */ 00449 contactsRead(); 00450 00451 QMessageBox::information( this, 00452 tr("Information"), 00453 tr("Phonebook from %1 restored" ) 00454 .arg( m_FileName ) 00455 ); 00456 } 00457 00458 setLedGreen(); 00459 } 00460 else 00461 { 00462 QMessageBox::warning( this, 00463 tr("Warning"), 00464 tr("Phone is not connected") 00465 ); 00466 } 00467 } 00468 00469 00470 /** 00471 * Dieser Slot erstellt ein Textfile Backup aus allen Kontakten. 00472 */ 00473 void BluePhone::contactsBackup() 00474 { 00475 if (myLink.getState()) 00476 { 00477 /* nur sichern, wenn das Telephonbuch bereits gelesen wurde */ 00478 if (listViewContacts->childCount() != 0) 00479 { 00480 /* "Save File" Dialog */ 00481 m_FileName = QFileDialog::getSaveFileName( 00482 tr("/home"), 00483 tr("Text files (*.txt);;All files (*.*)"), 00484 this, 00485 tr("Save File"), 00486 tr("Save Phonebook Backup As") 00487 ); 00488 00489 /* liefert das erste Item aus listViewContacts zurueck */ 00490 QListViewItem *Contact = listViewContacts->firstChild(); 00491 00492 /* Hat der User ein File gewaehlt oder Cancel gedrueckt? */ 00493 if (m_FileName) 00494 { 00495 /* was aus der guten, alten 3. Semester Zeit. Oeffne einen ofstream */ 00496 std::ofstream outputFile(m_FileName.latin1()); 00497 00498 /* Spitze listViewContacts in das outputFile ab */ 00499 while (Contact) 00500 { 00501 outputFile << Contact->text(0).latin1() << ":"; 00502 outputFile << Contact->text(1).latin1() << ":"; 00503 outputFile << Contact->text(2).latin1() << ":"; 00504 outputFile << Contact->text(3).latin1() << "\n"; 00505 00506 Contact = Contact->nextSibling(); 00507 } 00508 00509 QMessageBox::information( this, 00510 tr("Information"), 00511 tr("Phonebook as %1 saved" ) 00512 .arg( m_FileName ) 00513 ); 00514 } 00515 } 00516 else 00517 { 00518 QMessageBox::information( this, 00519 tr("Information"), 00520 tr("Please read the phonebook first") 00521 ); 00522 } 00523 00524 setLedGreen(); 00525 } 00526 else 00527 { 00528 QMessageBox::warning( this, 00529 tr("Warning"), 00530 tr("Phone is not connected") 00531 ); 00532 } 00533 } 00534 00535 00536 /** 00537 * Dieser Slot loescht den selektierten Kontakt. 00538 */ 00539 void BluePhone::contactsDelete() 00540 { 00541 if (myLink.getState()) 00542 { 00543 /* liefert das selektierte Item aus listViewContacts zurueck */ 00544 QListViewItem *selectedContact = listViewContacts->selectedItem(); 00545 00546 /* selectedItem liefert 0 zurueck, falls keine Selektion besteht */ 00547 if (selectedContact != 0) 00548 { 00549 /* Inhalt von selectedContact in die privaten Variablen abspeichern. */ 00550 m_phoneContactId = selectedContact->text(0); 00551 m_phoneContactName = selectedContact->text(2); 00552 00553 /* User abfragen, ob er wirklich loeschen will */ 00554 bool MessageboxAnswer = QMessageBox::question( this, 00555 tr("Question"), 00556 tr("Do you really want to delete contact %1 ?") 00557 .arg( m_phoneContactName ), 00558 tr("&No"), tr("&Yes"), 00559 QString::null, 1, 0 ); 00560 00561 if (MessageboxAnswer) 00562 { 00563 /* setze das AT Kommando fuer das Telephon zusammen. Siehe AT Referenz. */ 00564 m_AtCommand = "at+cpbw="; 00565 m_AtCommand.append(m_phoneContactId); 00566 m_AtCommand.append("\r"); 00567 00568 /* uebermittle dem Telephon den zu leoschenden Eintrag */ 00569 myLink.talktoPhone(m_Port, m_AtCommand); 00570 00571 /* Lese das Telephonbuch vom Telephon ein. So kann der User ueberpruefen, on alles geklappt hat */ 00572 contactsRead(); 00573 } 00574 00575 setLedGreen(); 00576 00577 } 00578 else 00579 { 00580 QMessageBox::information( this, 00581 tr("Information"), 00582 tr("Please select a contact") 00583 ); 00584 } 00585 00586 setLedGreen(); 00587 } 00588 else 00589 { 00590 QMessageBox::warning( this, 00591 tr("Warning"), 00592 tr("Phone is not connected") 00593 ); 00594 } 00595 } 00596 00597 00598 /** 00599 * Dieser Slot editiert den selektierten Kontakt. 00600 */ 00601 void BluePhone::contactsEdit() 00602 { 00603 if (myLink.getState()) 00604 { 00605 /* liefert das selektierte Item aus listViewContacts zurueck */ 00606 QListViewItem *selectedContact = listViewContacts->selectedItem(); 00607 00608 /* selectedItem liefert 0 zurueck, falls keine Selektion besteht */ 00609 if (selectedContact != 0) 00610 { 00611 /* Inhalt von selectedContact in die privaten Variablen abspeichern. */ 00612 m_phoneContactId = selectedContact->text(0); 00613 m_phoneContactType = selectedContact->text(1); 00614 m_phoneContactName = selectedContact->text(2); 00615 m_phoneContactNumber = selectedContact->text(3); 00616 00617 /* Erstelle einen EditContact Dialog, 00618 * Ich verwende fuer Edit den selben Dialog wie fuer New, hier editiere ich, also geht als Parameter 5 "edit" mit 00619 * Weiter braucht ein Edit Dialog braucht die Daten des selektierten Eintrages, Parameter 6 - 9 00620 */ 00621 NewContact *myEditContactDlg = new NewContact(this, 0, false, 0, "edit", m_phoneContactId, m_phoneContactType, m_phoneContactName, m_phoneContactNumber); 00622 00623 /* Erstelle eine Signal-Slot Verbindung 00624 von: myEditContactDlg::transmitContact (Quelle rsp. Signal) 00625 zu: this::sendContactToPhone (this = BluePhone, Senke rsp. Slot) 00626 Es werden die folgenden Parameter uebermittelt: ContactId, ContactType, ContactName, ContactNumber*/ 00627 QObject::connect( 00628 myEditContactDlg, SIGNAL(transmitContact(const QString&, const QString&, const QString&, const QString&)), 00629 this, SLOT(sendContactToPhone(const QString&, const QString&, const QString&, const QString&)) 00630 ); 00631 00632 /* Erstelle eine Signal-Slot Verbindung fuer die gruene LED Status Anzeige. */ 00633 QObject::connect( 00634 myEditContactDlg, SIGNAL(transmitLedStateGreen()), 00635 this, SLOT(setLedGreen()) 00636 ); 00637 00638 /* Setzte die gelbe LED. Dies muss leider hier geschehen, ein Aufruf vom "Send" Button des myEditContactDlg 00639 her kommt zu spaet, da der Fensterinhalt des Hauptfensters wird erst nach schliessen des Dialoges 00640 neu gezeichnet wird. */ 00641 setLedOrange(); 00642 00643 /* Zeige den NewContact Dialog an */ 00644 myEditContactDlg->show(); 00645 } 00646 else 00647 { 00648 QMessageBox::information( this, 00649 tr("Information"), 00650 tr("Please select a contact") 00651 ); 00652 } 00653 00654 setLedGreen(); 00655 } 00656 else 00657 { 00658 QMessageBox::warning( this, 00659 tr("Warning"), 00660 tr("Phone is not connected") 00661 ); 00662 } 00663 } 00664 00665 00666 /** 00667 * Dieser Slot erstellt einen neuen Kontakt. 00668 */ 00669 void BluePhone::contactsNew() 00670 { 00671 if (myLink.getState()) 00672 { 00673 /* Erstelle einen NewContact Dialog. Dies ist der default, deshalb keine weiteren Parameter an den Konstruktor. */ 00674 NewContact *myNewContactDlg = new NewContact(this); 00675 00676 /* Erstelle eine Signal-Slot Verbindung 00677 von: myNewContactDlg::transmitContact (Quelle rsp. Signal) 00678 zu: this::createNewContact (this = BluePhone, Senke rsp. Slot) 00679 Es werden die folgenden Parameter uebermittelt: ContactId, ContactType, ContactName, ContactNumber*/ 00680 QObject::connect( 00681 myNewContactDlg, SIGNAL(transmitContact(const QString&, const QString&, const QString&, const QString&)), 00682 this, SLOT(sendContactToPhone(const QString&, const QString&, const QString&, const QString&)) 00683 ); 00684 00685 /* Erstelle eine Signal-Slot Verbindung fuer die gruene LED Status Anzeige. */ 00686 QObject::connect( 00687 myNewContactDlg, SIGNAL(transmitLedStateGreen()), 00688 this, SLOT(setLedGreen()) ); 00689 00690 /* Setzte die gelbe LED. Dies muss leider hier geschehen, ein Aufruf vom "Send" Button des myNewContactDlg 00691 her kommt zu spaet, da der Fensterinhalt des Hauptfensters wird erst nach schliessen des Dialoges 00692 neu gezeichnet wird. */ 00693 setLedOrange(); 00694 00695 /* Zeige den NewContact Dialog an */ 00696 myNewContactDlg->show(); 00697 00698 00699 } 00700 else 00701 { 00702 QMessageBox::warning( this, 00703 tr("Warning"), 00704 tr("Phone is not connected") 00705 ); 00706 } 00707 } 00708 00709 00710 /** 00711 * Dieser Slot liest das Telephonbuch des Telephons ein. 00712 */ 00713 void BluePhone::contactsRead() 00714 { 00715 if (myLink.getState()) 00716 { 00717 listViewContacts->clear(); 00718 00719 /* teile dem Telephon mit, dass wir das Telephonbuch des Flash Speichers benutzen wollen. (ME) 00720 weitere waeren: SM: Simcard, BC: Business Card, usw. Siehe AT-Ref Seite 102 */ 00721 myLink.talktoPhone(m_Port, "at+cpbs=\"ME\"\r"); 00722 00723 /* lese die maximale Anzahl Telephonbuch Entraege aus */ 00724 m_phoneAnswer = myLink.talktoPhone(m_Port, "at+cpbr=?\r"); 00725 m_phoneContactCount = m_phoneAnswer.join(":"); 00726 m_phoneContactCount = m_phoneContactCount.section(':',2,2); 00727 m_phoneContactCount = m_phoneContactCount.section(')',0,0); 00728 m_phoneContactCount = m_phoneContactCount.section('(',1,1); 00729 m_phoneContactCount = m_phoneContactCount.section('-',1,1); 00730 00731 /* lese das gesamte Telephonbuch aus. eine Abfrage nur der belegten Plaetze ist nicht moeglich*/ 00732 m_phoneAnswer = myLink.talktoPhone(m_Port, "at+cpbr=1,"+m_phoneContactCount+"\r"); 00733 00734 /* spitze die Eintraege mit Hilfe des QStringList Iterators in listViewContacts ab. Siehe QT Doku zu QStringList.*/ 00735 for (QStringList::ConstIterator it = m_phoneAnswer.begin(); it != m_phoneAnswer.end(); ++it) 00736 { 00737 /* Zeichensatz konvertieren. Siehe BlueConvert */ 00738 m_phoneContactEntry.setLatin1(*it); 00739 m_phoneContactEntry = myConvert.convert_from_gsm(m_phoneContactEntry); 00740 00741 /* Status Meldungen wie OK und so sollen nicht abgespitzt werden. Alle "richtigen" Eintraege beginnen mit +CPBR */ 00742 if (m_phoneContactEntry.contains("+CPBR:")) 00743 { 00744 /* Ermittle die einzeln Werte des Eintrages*/ 00745 m_phoneContactEntry = m_phoneContactEntry.section(':',1,1); 00746 00747 m_phoneContactId = m_phoneContactEntry.section(',',0,0); 00748 m_phoneContactId = m_phoneContactId.stripWhiteSpace(); 00749 00750 m_phoneContactType = m_phoneContactEntry.section(',',3,3); 00751 m_phoneContactType = m_phoneContactType.section('/',1,1); 00752 m_phoneContactType = m_phoneContactType.left(1); 00753 00754 if ( m_phoneContactType == "H" ) 00755 { m_phoneContactType = "Home"; } 00756 else if ( m_phoneContactType == "W" ) 00757 { m_phoneContactType = "Work"; } 00758 else if ( m_phoneContactType == "M" ) 00759 { m_phoneContactType = "Mobile"; } 00760 else if ( m_phoneContactType == "F" ) 00761 { m_phoneContactType = "Fax"; } 00762 else 00763 { m_phoneContactType = "Other"; } 00764 00765 m_phoneContactName = m_phoneContactEntry.section(',',3,3); 00766 m_phoneContactName = m_phoneContactName.section('/',0,0); 00767 m_phoneContactName = m_phoneContactName.section('"',1,1); 00768 00769 m_phoneContactNumber = m_phoneContactEntry.section(',',1,1); 00770 m_phoneContactNumber = m_phoneContactNumber.section('"',1,1); 00771 00772 00773 /* Erstelle mit den gewonnenen Werten ein neues QListViewItem in listViewContacts */ 00774 new QListViewItem(listViewContacts, m_phoneContactId, m_phoneContactType, m_phoneContactName, m_phoneContactNumber); 00775 } 00776 } 00777 00778 /* Sortiere die Eintraege dem Namen nach */ 00779 listViewContacts->setSorting(2); 00780 listViewContacts->sort(); 00781 00782 /* Vestecke die ID Spalte der Kontakte Ansicht. BluePhone braucht diese Info, der Benutzer nicht. */ 00783 //DOESNOTWORK 00784 //listViewContacts->hideColumn(0); 00785 00786 setLedGreen(); 00787 } 00788 else 00789 { 00790 QMessageBox::warning( this, 00791 tr("Warning"), 00792 tr("Phone is not connected") 00793 ); 00794 } 00795 } 00796 00797 00798 /** 00799 * Dieser Slot erstellt ein neues SMS. 00800 */ 00801 void BluePhone::smsNew() 00802 { 00803 if (myLink.getState()) 00804 { 00805 /* Erstelle einen NewSms Dialog. Dies ist der default, deshalb keine weiteren Parameter an den Konstruktor. */ 00806 NewSms *myNewSmsDlg = new NewSms(this); 00807 00808 /* Erstelle eine Signal-Slot Verbindung 00809 von: myNewSmsDlg::transmitSms (Quelle rsp. Signal) 00810 zu: this::sendSmsToPhone (this = BluePhone, Senke rsp. Slot) 00811 Es werden die folgenden Parameter uebermittelt: QString Receiver, QString Message, int index, int id */ 00812 QObject::connect( 00813 myNewSmsDlg, SIGNAL(transmitSms(const QString&, const QString&, int, int)), 00814 this, SLOT(sendSmsToPhone(const QString&, const QString&, int, int)) 00815 ); 00816 00817 /* Erstelle eine Signal-Slot Verbindung fuer die gruene LED Status Anzeige. */ 00818 QObject::connect( 00819 myNewSmsDlg, SIGNAL(transmitLedStateGreen()), 00820 this, SLOT(setLedGreen()) 00821 ); 00822 00823 /* Setzte die gelbe LED. Dies muss leider hier geschehen, ein Aufruf vom "Send" Button des myNewSmsDlg 00824 her kommt zu spaet, da der Fensterinhalt des Hauptfensters wird erst nach schliessen des Dialoges 00825 neu gezeichnet wird. */ 00826 setLedOrange(); 00827 00828 /* Zeige den NewSms Dialog an */ 00829 myNewSmsDlg->show(); 00830 } 00831 else 00832 { 00833 QMessageBox::warning( this, 00834 tr("Warning"), 00835 tr("Phone is not connected") 00836 ); 00837 } 00838 } 00839 00840 00841 /** 00842 * Dieser Slot loescht alle SMS auf dem Telephon. 00843 */ 00844 void BluePhone::smsDeleteAll() 00845 { 00846 if (myLink.getState()) 00847 { 00848 /* nur loeschen, wenn die SMS Liste bereits gelesen wurde */ 00849 if (listViewSms->childCount() != 0) 00850 { 00851 /* User abfragen, ob er wirklich alle SMS loeschen will */ 00852 bool MessageboxAnswer = QMessageBox::question( this, 00853 tr("Question"), 00854 tr("Do you really want to delete all SMS on your phone?"), 00855 tr("&No"), tr("&Yes"), 00856 QString::null, 1, 0 ); 00857 00858 if (MessageboxAnswer) 00859 { 00860 /* teile dem Telephon mit, dass wir die SMS Daten des Flash Speichers benutzen wollen. (ME) 00861 weitere waeren: SM: Simcard, TL: Templeate. */ 00862 myLink.talktoPhone(m_Port, "at+cpms=\"ME\"\r"); 00863 00864 /* lese den ersten Eintrag aus der SMS Liste. */ 00865 QListViewItem *Sms = listViewSms->firstChild(); 00866 00867 /* loesche die SMS der Reihe nach. */ 00868 while(Sms) 00869 { 00870 /* setze das AT Kommando fuer das Telephon zusammen. Siehe AT Referenz. */ 00871 m_AtCommand = "at+cmgd="; 00872 m_AtCommand.append(Sms->text(0)); 00873 m_AtCommand.append("\r"); 00874 00875 /* uebermittle dem Telephon den zu leoschenden Eintrag */ 00876 myLink.talktoPhone(m_Port, m_AtCommand); 00877 00878 /* Gehe zum naechsten SMS. */ 00879 Sms = Sms->nextSibling(); 00880 } 00881 00882 /* Lese die SMS Liste vom Telephon ein. So kann der User ueberpruefen, on alles geklappt hat */ 00883 smsRead(); 00884 } 00885 } 00886 else 00887 { 00888 QMessageBox::information( this, 00889 tr("Information"), 00890 tr("Please read the SMS list first") 00891 ); 00892 } 00893 00894 setLedGreen(); 00895 } 00896 else 00897 { 00898 QMessageBox::warning( this, 00899 tr("Warning"), 00900 tr("Phone is not connected") 00901 ); 00902 } 00903 } 00904 00905 00906 /** 00907 * Dieser Slot loescht ein SMS. 00908 */ 00909 void BluePhone::smsDelete() 00910 { 00911 if (myLink.getState()) 00912 { 00913 /* liefert das selektierte Item aus listViewSms zurueck */ 00914 QListViewItem *selectedSms = listViewSms->selectedItem(); 00915 00916 /* selectedItem liefert 0 zurueck, falls keine Selektion besteht */ 00917 if (selectedSms != 0) 00918 { 00919 /* Inhalt von listViewSms in die privaten Variablen abspeichern. */ 00920 m_phoneSmsId = selectedSms->text(0); 00921 00922 /* User abfragen, ob er wirklich loeschen will */ 00923 bool MessageboxAnswer = QMessageBox::question( this, 00924 tr("Question"), 00925 tr("Do you really want to delete SMS with ID %1 ?") 00926 .arg( m_phoneSmsId ), 00927 tr("&No"), tr("&Yes"), 00928 QString::null, 1, 0 ); 00929 00930 if (MessageboxAnswer) 00931 { 00932 /* teile dem Telephon mit, dass wir die SMS Daten des Flash Speichers benutzen wollen. (ME) 00933 weitere waeren: SM: Simcard, TL: Templeate. */ 00934 myLink.talktoPhone(m_Port, "at+cpms=\"ME\"\r"); 00935 00936 /* setze das AT Kommando fuer das Telephon zusammen. Siehe AT Referenz. */ 00937 m_AtCommand = "at+cmgd="; 00938 m_AtCommand.append(m_phoneSmsId); 00939 m_AtCommand.append("\r"); 00940 00941 /* uebermittle dem Telephon den zu leoschenden Eintrag */ 00942 myLink.talktoPhone(m_Port, m_AtCommand); 00943 00944 /* Lese die SMS Liste vom Telephon ein. So kann der User ueberpruefen, on alles geklappt hat */ 00945 smsRead(); 00946 } 00947 } 00948 else 00949 { 00950 QMessageBox::information( this, 00951 tr("Information"), 00952 tr("Please select a SMS") 00953 ); 00954 } 00955 00956 setLedGreen(); 00957 } 00958 else 00959 { 00960 QMessageBox::warning( this, 00961 tr("Warning"), 00962 tr("Phone is not connected") 00963 ); 00964 } 00965 } 00966 00967 00968 /** 00969 * Dieser Slot speichert alle Kurznachrichten in einem Textfile ab. 00970 */ 00971 void BluePhone::smsSaveAll() 00972 { 00973 if (myLink.getState()) 00974 { 00975 /* nur sichern, wenn die SMS Liste bereits gelesen wurde */ 00976 if (listViewSms->childCount() != 0) 00977 { 00978 /* "Save File" Dialog */ 00979 m_FileName = QFileDialog::getSaveFileName( 00980 tr("/home"), 00981 tr("Text files (*.txt);;All files (*.*)"), 00982 this, 00983 tr("Save File"), 00984 tr("Save SMS Backup As") 00985 ); 00986 00987 /* liefert das erste Item aus listViewSms zurueck */ 00988 QListViewItem *Sms = listViewSms->firstChild(); 00989 00990 /* Hat der User ein File gewaehlt oder Cancel gedrueckt? */ 00991 if (m_FileName) 00992 { 00993 /* was aus der guten, alten 3. Semester Zeit. Oeffne einen ofstream */ 00994 std::ofstream outputFile(m_FileName.latin1()); 00995 00996 /* Spitze listViewSms in das outputFile ab */ 00997 while (Sms) 00998 { 00999 outputFile << "From: " << Sms->text(3).latin1() << " "; 01000 outputFile << "Date: " << Sms->text(2).latin1() << " "; 01001 outputFile << "State: " << Sms->text(1).latin1() << " \n"; 01002 outputFile << "Message: " << Sms->text(4).latin1() << " \n\n\n"; 01003 01004 Sms = Sms->nextSibling(); 01005 } 01006 01007 QMessageBox::information( this, 01008 tr("Information"), 01009 tr("List of all SMS as %1 saved" ) 01010 .arg( m_FileName ) 01011 ); 01012 } 01013 } 01014 else 01015 { 01016 QMessageBox::information( this, 01017 tr("Information"), 01018 tr("Please read the SMS list first") 01019 ); 01020 } 01021 } 01022 else 01023 { 01024 QMessageBox::warning( this, 01025 tr("Warning"), 01026 tr("Phone is not connected") 01027 ); 01028 } 01029 } 01030 01031 01032 /** 01033 * Dieser Slot speichert eine Kurznachricht in einem Textfile ab. 01034 */ 01035 void BluePhone::smsSave() 01036 { 01037 if (myLink.getState()) 01038 { 01039 /* liefert das selektierte Item aus listViewSms zurueck */ 01040 QListViewItem *selectedSms = listViewSms->selectedItem(); 01041 01042 /* selectedItem liefert 0 zurueck, falls keine Selektion besteht */ 01043 if (selectedSms != 0) 01044 { 01045 /* "Save File" Dialog */ 01046 m_FileName = QFileDialog::getSaveFileName( 01047 tr("/home"), 01048 tr("Text files (*.txt);;All files (*.*)"), 01049 this, 01050 tr("Save File"), 01051 tr("Save SMS Backup As") 01052 ); 01053 01054 /* Hat der User ein File gewaehlt oder Cancel gedrueckt? */ 01055 if (m_FileName) 01056 { 01057 /* was aus der guten, alten 3. Semester Zeit. Oeffne einen ofstream */ 01058 std::ofstream outputFile(m_FileName.latin1()); 01059 01060 /* Spitze das selektierte SMS in das outputFile ab */ 01061 outputFile << "From: " << selectedSms->text(3).latin1() << " "; 01062 outputFile << "Date: " << selectedSms->text(2).latin1() << " "; 01063 outputFile << "State: " << selectedSms->text(1).latin1() << " \n"; 01064 outputFile << "Message: " << selectedSms->text(4).latin1() << " \n"; 01065 01066 QMessageBox::information( this, 01067 tr("Information"), 01068 tr("SMS as %1 saved" ) 01069 .arg( m_FileName ) 01070 ); 01071 } 01072 } 01073 else 01074 { 01075 QMessageBox::information( this, 01076 tr("Information"), 01077 tr("Please select a SMS first") 01078 ); 01079 } 01080 } 01081 else 01082 { 01083 QMessageBox::warning( this, 01084 tr("Warning"), 01085 tr("Phone is not connected") 01086 ); 01087 } 01088 } 01089 01090 01091 /** 01092 * Dieser Slot liest die Kurznachrichten vom Telephon ein. 01093 */ 01094 void BluePhone::smsRead() 01095 { 01096 if (myLink.getState()) 01097 { 01098 listViewSms->clear(); 01099 01100 /* teile dem Telephon mit, dass wir die SMS Daten des Flash Speichers benutzen wollen. (ME) 01101 weitere waeren: SM: Simcard, TL: Templeate. */ 01102 myLink.talktoPhone(m_Port, "at+cpms=\"ME\"\r"); 01103 01104 /* lese alle SMS aus dem Telephon aus. Der Parameter bestimmt: 01105 0 = empfangene, ungelesene Nachrichten, 01106 1 = empfangene, gelesene Nachrichten, 01107 4 = alle Nachrichten, 01108 16 = template Nachrichten */ 01109 m_phoneAnswer = myLink.talktoPhone(m_Port, "at+cmgl=4\r"); 01110 01111 /* spitze die Eintraege mit Hilfe des QStringList Iterators in listViewSms ab. Siehe QT Doku zu QStringList.*/ 01112 for (QStringList::ConstIterator it = m_phoneAnswer.begin(); it != m_phoneAnswer.end(); ++it) 01113 { 01114 /* Zeichensatz konvertieren. */ 01115 m_phoneSmsEntry.setLatin1(*it); 01116 01117 /* Status Meldungen wie OK und so sollen nicht abgespitzt werden. Alle "richtigen" Eintraege beginnen mit +CMGL */ 01118 if (m_phoneSmsEntry.contains("+CMGL:")) 01119 { 01120 /* Ermittle die einzeln Werte des Eintrages*/ 01121 m_phoneSmsId = m_phoneSmsEntry.section(':',1,1); 01122 m_phoneSmsId = m_phoneSmsId.section(',',0,0); 01123 m_phoneSmsId = m_phoneSmsId.stripWhiteSpace(); 01124 01125 m_phoneSmsStatus = m_phoneSmsEntry.section(',',1,1); 01126 01127 if ( m_phoneSmsStatus == "3" ) 01128 { m_phoneSmsStatus = "Sent"; } 01129 else if ( m_phoneSmsStatus == "1" ) 01130 { m_phoneSmsStatus = "Read"; } 01131 else if ( m_phoneSmsStatus == "0" ) 01132 { m_phoneSmsStatus = "Unread"; } 01133 else 01134 { m_phoneSmsStatus = "Unknown"; } 01135 01136 /* Eine SMS besteht aus zwei Teilen. Der erste enthaelt die ID und den Status, 01137 der zweite die Nummer und die Message in einem "IRA-character long hexadecimal" Format 01138 (Terminologie Ericsson). Nun wollen wir diese Daten, deshalb wechseln wir zum naechsten Eintrag */ 01139 it++; 01140 01141 /* erneut Zeichensatz konvertieren. Irgendwie hat mir dieses Telephon zu viele Datenformate... */ 01142 m_phoneSmsEntry.setLatin1(*it); 01143 01144 /* Erstelle ein neues BlueConvert Objekt */ 01145 BlueConvert *smsData = new BlueConvert(); 01146 01147 /* Uebersetze das 7Bit Hex Format(PDU) in einen nomalen uuencode String */ 01148 smsData->extractPduData(m_phoneSmsEntry); 01149 01150 /* Hole die gewonnenen Daten ab. */ 01151 m_phoneSmsNumber = smsData->getSender(); 01152 m_phoneSmsMessage = smsData->getMessage(); 01153 m_phoneSmsDateTmp = smsData->getDate(); 01154 01155 /* Formatiere das Datum etwas leserlicher. Gesendete SMS haben kein Datum. */ 01156 if ( m_phoneSmsStatus == "Sent" ) 01157 { 01158 m_phoneSmsDate = " n.a."; 01159 } 01160 else 01161 { 01162 m_phoneSmsDate = m_phoneSmsDateTmp.mid(0,2); 01163 m_phoneSmsDate.append("-"); 01164 m_phoneSmsDate.append(m_phoneSmsDateTmp.mid(2,2)); 01165 m_phoneSmsDate.append("-"); 01166 m_phoneSmsDate.append(m_phoneSmsDateTmp.mid(4,2)); 01167 m_phoneSmsDate.append(" "); 01168 m_phoneSmsDate.append(m_phoneSmsDateTmp.mid(6,2)); 01169 m_phoneSmsDate.append(":"); 01170 m_phoneSmsDate.append(m_phoneSmsDateTmp.mid(8,2)); 01171 } 01172 01173 /* Erstelle mit den gewonnenen Werten ein neues QListViewItem in listViewContacts */ 01174 new QListViewItem(listViewSms, m_phoneSmsId, m_phoneSmsStatus, m_phoneSmsDate, m_phoneSmsNumber, m_phoneSmsMessage); 01175 01176 01177 /* Zu new gehoert delete. Ich will ja kein mega Speicher fressendes mini Programm schreiben. */ 01178 delete smsData; 01179 } 01180 } 01181 01182 /* Sortiere die Eintraege absteigend dem Datum nach. */ 01183 listViewSms->setSorting(2, false); 01184 listViewSms->sort(); 01185 01186 /* Vestecke die ID Spalte der SMS Ansicht. BluePhone braucht diese Info, der Benutzer nicht. */ 01187 //DOESNOTWORK 01188 //listViewSms->hideColumn(0); 01189 01190 setLedGreen(); 01191 } 01192 else 01193 { 01194 QMessageBox::warning( this, 01195 tr("Warning"), 01196 tr("Phone is not connected") 01197 ); 01198 } 01199 } 01200 01201 01202 /** 01203 * Dieser Slot zeigt eine Nachricht in einer Messagebox an. 01204 */ 01205 void BluePhone::smsShow() 01206 { 01207 if (myLink.getState()) 01208 { 01209 /* liefert das selektierte Item aus listViewSms zurueck */ 01210 QListViewItem *selectedSms = listViewSms->selectedItem(); 01211 01212 /* selectedItem liefert 0 zurueck, falls keine Selektion besteht */ 01213 if (selectedSms != 0) 01214 { 01215 /* Inhalt von listViewSms in die privaten Variablen abspeichern. */ 01216 m_phoneSmsId = selectedSms->text(0); 01217 m_phoneSmsStatus = selectedSms->text(1); 01218 m_phoneSmsDate = selectedSms->text(2); 01219 m_phoneSmsNumber = selectedSms->text(3); 01220 m_phoneSmsMessage = selectedSms->text(4); 01221 01222 m_phoneSmsToShow = "Message from: "; 01223 m_phoneSmsToShow.append(m_phoneSmsNumber); 01224 m_phoneSmsToShow.append("\nReceived at: "); 01225 m_phoneSmsToShow.append(m_phoneSmsDate); 01226 m_phoneSmsToShow.append("\n\nMessage: "); 01227 m_phoneSmsToShow.append(m_phoneSmsMessage); 01228 m_phoneSmsToShow.append("\n\nReply?"); 01229 01230 bool MessageboxAnswer = QMessageBox::information( this, 01231 tr("View Message"), 01232 tr("%1") 01233 .arg( m_phoneSmsToShow ), 01234 tr("&Yes"), tr("&No"), 01235 QString::null, 1, 0 ); 01236 01237 if (!MessageboxAnswer) 01238 { 01239 /* Zeige den ReplySms Dialog an */ 01240 smsReply(); 01241 } 01242 } 01243 else 01244 { 01245 QMessageBox::information( this, 01246 tr("Information"), 01247 tr("Please select a Message") 01248 ); 01249 } 01250 } 01251 else 01252 { 01253 QMessageBox::warning( this, 01254 tr("Warning"), 01255 tr("Phone is not connected") 01256 ); 01257 } 01258 } 01259 01260 01261 /** 01262 * Dieser Slot bietet die Moeglichkeit, eine Nachricht zu beantworteten. 01263 */ 01264 void BluePhone::smsReply() 01265 { 01266 if (myLink.getState()) 01267 { 01268 /* liefert das selektierte Item aus listViewSms zurueck */ 01269 QListViewItem *selectedSms = listViewSms->selectedItem(); 01270 01271 /* selectedItem liefert 0 zurueck, falls keine Selektion besteht */ 01272 if (selectedSms != 0) 01273 { 01274 /* Inhalt von listViewSms in die privaten Variablen abspeichern. */ 01275 m_phoneSmsNumber = selectedSms->text(3); 01276 m_phoneSmsMessage = selectedSms->text(4); 01277 01278 /* Erstelle einen NewSms Dialog, teile ihm mit, dass dies eine Antwort ist (reply) und 01279 uebergebe den Sender und die Original Message als weitere Parameter an den Konstruktor. */ 01280 NewSms *myNewSmsDlg = new NewSms(this, 0, false, 0, "reply", m_phoneSmsNumber, m_phoneSmsMessage); 01281 01282 /* Erstelle eine Signal-Slot Verbindung 01283 von: myNewSmsDlg::transmitSms (Quelle rsp. Signal) 01284 zu: this::sendSmsToPhone (this = BluePhone, Senke rsp. Slot) 01285 Es werden die folgenden Parameter uebermittelt: QString Receiver, QString Message, int index, int id */ 01286 QObject::connect( 01287 myNewSmsDlg, SIGNAL(transmitSms(const QString&, const QString&, int, int)), 01288 this, SLOT(sendSmsToPhone(const QString&, const QString&, int, int)) 01289 ); 01290 01291 /* Erstelle eine Signal-Slot Verbindung fuer die gruene LED Status Anzeige. */ 01292 QObject::connect( 01293 myNewSmsDlg, SIGNAL(transmitLedStateGreen()), 01294 this, SLOT(setLedGreen()) 01295 ); 01296 01297 /* Setzte die gelbe LED. Dies muss leider hier geschehen, ein Aufruf vom "Send" Button des myNewSmsDlg 01298 her kommt zu spaet, da der Fensterinhalt des Hauptfensters wird erst nach schliessen des Dialoges 01299 neu gezeichnet wird. */ 01300 setLedOrange(); 01301 01302 /* Zeige den NewSms Dialog an */ 01303 myNewSmsDlg->show(); 01304 } 01305 else 01306 { 01307 QMessageBox::information( this, 01308 tr("Information"), 01309 tr("Please select a Message") 01310 ); 01311 } 01312 } 01313 else 01314 { 01315 QMessageBox::warning( this, 01316 tr("Warning"), 01317 tr("Phone is not connected") 01318 ); 01319 } 01320 } 01321 01322 01323 /** 01324 * Dieser Slot sendet, ueber Obex, eine Datei an das Telphon. 01325 */ 01326 void BluePhone::fileSend() 01327 { 01328 if (myLink.getState()) 01329 { 01330 struct BlueObex session; 01331 obex_t *handle; 01332 01333 session.client_done = false; 01334 session.filename = m_UploadFilePath; 01335 01336 /* Initialisiere OBEX */ 01337 if (m_Device.contains("ircomm")) 01338 { 01339 handle = obexInit(&session, 1, "", 0); 01340 } 01341 else if (m_Device.contains("rfcomm")) 01342 { 01343 handle = obexInit(&session, 2, m_BtAddress, m_BtChannelInt); 01344 } 01345 else 01346 { 01347 QMessageBox::critical( this, 01348 tr("Error"), 01349 tr("Could not establish OBEX connection to %1" ) 01350 .arg( m_Device ) 01351 ); 01352 return; 01353 } 01354 01355 if (!handle) 01356 { 01357 QMessageBox::warning( this, 01358 tr("Warning"), 01359 tr("Invalid OBEX handle") 01360 ); 01361 return; 01362 } 01363 01364 /* Stelle die Obex Verbindung her */ 01365 if (obexConnect(handle)) 01366 { 01367 QMessageBox::warning( this, 01368 tr("Warning"), 01369 tr("OBEX connection error") 01370 ); 01371 return; 01372 } 01373 01374 /* Lade die Datei auf das Telephon */ 01375 obexPutfile(handle, &session, m_UploadFileName); 01376 01377 if (obexDisconnect(handle)) 01378 { 01379 QMessageBox::warning( this, 01380 tr("Warning"), 01381 tr("OBEX disconnect error") 01382 ); 01383 return; 01384 } 01385 01386 setLedGreen(); 01387 } 01388 else 01389 { 01390 QMessageBox::warning( this, 01391 tr("Warning"), 01392 tr("Phone is not connected") 01393 ); 01394 } 01395 } 01396 01397 01398 /** 01399 * Dieser Slot dient zum Auswaehlen der Datei, die an das Telphon geschickt werden soll. 01400 */ 01401 void BluePhone::fileBrowse() 01402 { 01403 /* Zeige einen "Open File" Dialog */ 01404 m_UploadFilePath = QFileDialog::getOpenFileName( 01405 tr("/home"), 01406 tr("All files (*.*)"), 01407 this, 01408 tr("Open File"), 01409 tr("Open File to Upload") 01410 ); 01411 01412 lineEditFilePath->setText(m_UploadFilePath); 01413 01414 /* Passe den Namen (Pfad) fuer das Telephon kompatbel (nur Datainame) an */ 01415 if (m_UploadFilePath.contains("/")) 01416 { 01417 m_UploadFileName = m_UploadFilePath.right(m_UploadFilePath.length() - m_UploadFilePath.findRev("/") - 1); 01418 } 01419 else 01420 { 01421 m_UploadFileName = m_UploadFilePath; 01422 } 01423 01424 lineEditFileNameOnPhone->setText(m_UploadFileName); 01425 01426 /* zeige Informationen zur Datei an */ 01427 showMetaInfo(m_UploadFilePath); 01428 } 01429 01430 01431 /** 01432 * Dieser Slot liest einige generelle Informationen aus dem Telephon aus. 01433 * Diese sind: Hersteller, Modell, Revision, Status, Batterieladung 01434 */ 01435 void BluePhone::phoneGetInfo() 01436 { 01437 if (myLink.getState()) 01438 { 01439 /* Hersteller des Telephons abfragen und mit lineEditPhoneManufacturer anzeigen. */ 01440 m_phoneAnswer = myLink.talktoPhone(m_Port, "at+gmi\r"); 01441 m_phoneManufacturer = m_phoneAnswer.join(":"); 01442 m_phoneManufacturer = m_phoneManufacturer.section(':',1,1); 01443 lineEditPhoneManufacturer->setText(m_phoneManufacturer); 01444 01445 /* Model des Telephons abfragen und mit lineEditPhoneModel anzeigen. */ 01446 m_phoneAnswer = myLink.talktoPhone(m_Port, "at+gmm\r"); 01447 m_phoneModel = m_phoneAnswer.join(":"); 01448 m_phoneModel = m_phoneModel.section(':',1,1); 01449 lineEditPhoneModel->setText(m_phoneModel); 01450 01451 /* Revision des Telephons abfragen und mit lineEditPhoneRevision anzeigen. */ 01452 m_phoneAnswer = myLink.talktoPhone(m_Port, "at+gmr\r"); 01453 m_phoneRevision = m_phoneAnswer.join(":"); 01454 m_phoneRevision = m_phoneRevision.section(':',1,1); 01455 m_phoneRevision = m_phoneRevision.left(10); 01456 lineEditPhoneRevision->setText(m_phoneRevision); 01457 01458 /* Status des Telephons abfragen und mit lineEditPhoneStatus anzeigen. */ 01459 m_phoneAnswer = myLink.talktoPhone(m_Port, "at+cpas\r"); 01460 m_phoneStatus = m_phoneAnswer.join(":"); 01461 m_phoneStatus = m_phoneStatus.section(':',2,2); 01462 m_phoneStatus = m_phoneStatus.mid(1,1); 01463 01464 if (m_phoneStatus == "0") 01465 { 01466 m_phoneStatus = "Ready"; 01467 } 01468 else if (m_phoneStatus == "1") 01469 { 01470 m_phoneStatus = "Unavailable"; 01471 } 01472 else if (m_phoneStatus == "2") 01473 { 01474 m_phoneStatus = "Unknown"; 01475 } 01476 else if (m_phoneStatus == "3") 01477 { 01478 m_phoneStatus = "Ringing"; 01479 } 01480 else if (m_phoneStatus == "4") 01481 { 01482 m_phoneStatus = "Call in progress"; 01483 } 01484 else if (m_phoneStatus == "5") 01485 { 01486 m_phoneStatus = "Asleep"; 01487 } 01488 else 01489 { 01490 m_phoneStatus = "Loathly"; 01491 } 01492 01493 lineEditPhoneStatus->setText(m_phoneStatus); 01494 01495 /* Batterie Ladung des Telephons abfragen und mit progressBarPhoneBattery anzeigen. */ 01496 m_phoneAnswer = myLink.talktoPhone(m_Port, "at+cbc\r"); 01497 m_phoneBattery = m_phoneAnswer.join(":"); 01498 m_phoneBattery = m_phoneBattery.section(':',2,2); 01499 m_phoneBattery = m_phoneBattery.section(',',1,1); 01500 progressBarPhoneBattery->setProgress(m_phoneBattery.toInt()); 01501 01502 /* Setze den Text des lineEditPhoneConnected auf "Connected" */ 01503 lineEditPhoneConnected->setText("Connected"); 01504 01505 /* Die gruene LED soll leuchten */ 01506 setLedGreen(); 01507 } 01508 else 01509 { 01510 /* Setze den Text des lineEditPhoneConnected auf "Disconnected" */ 01511 lineEditPhoneConnected->setText("Disconnected"); 01512 01513 /* Loesche den Inhalt aller Felder */ 01514 lineEditPhoneManufacturer->clear(); 01515 lineEditPhoneModel->clear(); 01516 lineEditPhoneRevision->clear(); 01517 lineEditPhoneStatus->clear(); 01518 progressBarPhoneBattery->reset(); 01519 01520 /* Die rote LED soll leuchten */ 01521 setLedRed(); 01522 01523 } 01524 } 01525 01526 01527 /** 01528 * Dieser Slot schliesst die Verbindung mit dem Telephon. 01529 */ 01530 void BluePhone::phoneDisconnect() 01531 { 01532 /* Sind wir verbunden? */ 01533 if (myLink.getState()) 01534 { 01535 /* Eventuell mit Daten gefuellte Widgets leeren */ 01536 listViewSms->clear(); 01537 listViewContacts->clear(); 01538 01539 /* Serielle Verbindung trennen */ 01540 myLink.disconnectPhone(); 01541 01542 /* rfcomm Verbindung trennen */ 01543 myLink.disconnectRfcomm(m_Device); 01544 01545 /* Status Anzeigen leeren */ 01546 phoneGetInfo(); 01547 01548 } 01549 else 01550 { 01551 QMessageBox::information( this, 01552 tr("Information"), 01553 tr("Phone is already disconnected") 01554 ); 01555 setLedRed(); 01556 } 01557 } 01558 01559 01560 /** 01561 * Dieser Slot verbindet BluePhone mit dem Telephon. 01562 * Die Logik dieses Slots ist in BlueLink. 01563 */ 01564 void BluePhone::phoneConnect() 01565 { 01566 /* Sind wir schon schon verbunden? */ 01567 if (myLink.getState()) 01568 { 01569 QMessageBox::information( this, 01570 tr("Information"), 01571 tr("Phone is already connected") 01572 ); 01573 setLedGreen(); 01574 } 01575 else 01576 { 01577 /* Verbinde unser rfcomm Device mit dem entfernten Bluetooth Device (das Telephon). */ 01578 int rfcommState = myLink.connectRfcomm(m_Device, m_BtAddress); 01579 01580 /* rfcomm braucht etwas Zeit. */ 01581 usleep(3000); 01582 01583 if (!rfcommState) 01584 { 01585 QMessageBox::critical( this, 01586 tr("Error"), 01587 tr("Unable to connect rfcomm" ) 01588 ); 01589 } 01590 01591 01592 /* Baue die serielle (ezV24) Verbindung auf. */ 01593 myLink.connecttoPhone(m_Device); 01594 01595 /* Ermittle den ezv24 Port.*/ 01596 m_Port = myLink.getPort(); 01597 01598 if (m_Port==NULL) 01599 { 01600 QMessageBox::critical( this, 01601 tr("Error"), 01602 tr("Could not establish connection to %1\n" 01603 "Please try again, sometimes, there are some timing problems" ) 01604 .arg( m_Device ) 01605 ); 01606 } 01607 else 01608 { 01609 phoneGetInfo(); 01610 } 01611 } 01612 } 01613 01614 01615 /** 01616 * Dieser Slot zeigt die "About" Messagebox an. 01617 */ 01618 void BluePhone::helpAbout() 01619 { 01620 QMessageBox::about( this, 01621 tr("About - BluePhone"), 01622 tr("BluePhone - Version %1\n\n" 01623 "A tool to run a Sony Ericsson mobile phone from a PC\n\n" 01624 "(C) 2004 Thomas Gemperli - " 01625 "bluephone@gemperli.net\n" ) 01626 .arg( version ) 01627 ); 01628 } 01629 01630 01631 /** 01632 * Diesr Slot beendet das Programm. 01633 */ 01634 void BluePhone::fileExit() 01635 { 01636 if (myLink.getState()) 01637 { 01638 phoneDisconnect(); 01639 } 01640 01641 this->close(); 01642 } 01643 01644 01645 /** 01646 * Dieser Slot setzt die gruene LED rsp. diese "leuchtet", falls die Verbindung zum Telephon steht. 01647 */ 01648 void BluePhone::setLedGreen() 01649 { 01650 /* Sind wir mit dem Telephon verbunden? */ 01651 if (myLink.getState()) 01652 { 01653 kLedPhoneStateOrange->off(); 01654 kLedPhoneStateRed->off(); 01655 kLedPhoneStateGreen->on(); 01656 } 01657 else 01658 { 01659 setLedRed(); 01660 } 01661 } 01662 01663 /** 01664 * Dieser Slot setzt die orange LED rsp. diese "leuchtet" , falls die Verbindung zum Telephon steht. 01665 */ 01666 void BluePhone::setLedOrange() 01667 { 01668 /* Sind wir mit dem Telephon verbunden? */ 01669 if (myLink.getState()) 01670 { 01671 kLedPhoneStateGreen->off(); 01672 kLedPhoneStateRed->off(); 01673 kLedPhoneStateOrange->on(); 01674 } 01675 else 01676 { 01677 setLedRed(); 01678 } 01679 } 01680 01681 /** 01682 * Dieser Slot setzt die rote LED rsp. diese "leuchtet" 01683 */ 01684 void BluePhone::setLedRed() 01685 { 01686 kLedPhoneStateGreen->off(); 01687 kLedPhoneStateOrange->off(); 01688 kLedPhoneStateRed->on(); 01689 } 01690 01691 01692 /** 01693 * Dieser Slot sendet einen neuen oder editierten Kontakt an das Telephon. 01694 * Parameter: ContactId, ContactType, ContactName, ContactNumber 01695 */ 01696 void BluePhone::sendContactToPhone(const QString& ContactId, const QString& ContactType, const QString& ContactName, const QString& ContactNumber) 01697 { 01698 01699 /* teile dem Telephon mit, dass wir das Telephonbuch des Flash Speichers benutzen wollen. Mehr Infos siehe contactsRead */ 01700 myLink.talktoPhone(m_Port, "at+cpbs=\"ME\"\r"); 01701 01702 /* Parameter in die privaten Variablen abspeichern. Wie wir es gelernt haben :) */ 01703 m_phoneContactId = ContactId; 01704 m_phoneContactType = ContactType; 01705 m_phoneContactName = ContactName; 01706 m_phoneContactNumber = ContactNumber; 01707 01708 /* Der Zeichensatz von m_phoneContactName muss noch fuer das Telephon umgewandelt werden*/ 01709 m_phoneContactName = myConvert.convert_to_gsm(m_phoneContactName); 01710 01711 /* soll ein neuer Kontakt hinzugefuegt oder ein bestehender Kontakt geaendert werden? */ 01712 if ( m_phoneContactId == "generate" ) 01713 { 01714 m_AtCommand = "at+cpbw=,\""; 01715 } 01716 else 01717 { 01718 m_AtCommand = "at+cpbw="; 01719 m_AtCommand.append(m_phoneContactId); 01720 m_AtCommand.append(",\""); 01721 } 01722 01723 /* setze das AT Kommando fuer das Telephon zusammen. Siehe AT Referenz. Zum Glueck gab mir der C++ Gott QString ... */ 01724 m_AtCommand.append(m_phoneContactNumber); 01725 m_AtCommand.append("\",,\""); 01726 m_AtCommand.append(m_phoneContactName); 01727 m_AtCommand.append("/"); 01728 m_AtCommand.append(m_phoneContactType); 01729 m_AtCommand.append("\"\r"); 01730 01731 /* uebermittle dem Telephon den neuen Telephonbuch Eintrag */ 01732 myLink.talktoPhone(m_Port, m_AtCommand); 01733 01734 01735 /* Lese das Telephonbuch vom Telephon ein. So kann der User ueberpruefen, ob alles geklappt hat */ 01736 contactsRead(); 01737 } 01738 01739 01740 /** 01741 * Dieser Slot sendet ein SMS an das Telephon. 01742 * Parameter: QString Receiver, QString Message, int index, int id 01743 */ 01744 void BluePhone::sendSmsToPhone(const QString& Receiver, const QString& Message, int index, int id) 01745 { 01746 01747 m_phoneSmsNumber = Receiver; 01748 m_phoneSmsMessage = Message; 01749 m_index = index; 01750 m_id = id; 01751 01752 01753 /* Erstelle ein neues BlueConvert Objekt */ 01754 BlueConvert *smsData = new BlueConvert(); 01755 01756 /* Uebersetze die "normalen" uuencode Strings in einen 7Bit Hex PDU Block, den das Telephon benoetigt. */ 01757 smsData->createPduData(m_phoneSmsNumber, m_phoneSmsMessage, m_index, m_id); 01758 01759 /* Hole die erzeugte PDU */ 01760 m_PDU = smsData->getPdu(); 01761 01762 /* Zu new gehoert delete. Ich will ja kein mega Speicher fressendes mini Programm schreiben. */ 01763 delete smsData; 01764 01765 01766 /* Ermittle die Laenge der PDU */ 01767 m_PduLength.setNum((m_PDU.length() / 2) - 1); 01768 01769 /* setze das AT Kommando fuer das Telephon zusammen. Siehe AT Referenz. */ 01770 m_AtCommand = "at+cmgs="; 01771 m_AtCommand.append(m_PduLength); 01772 m_AtCommand.append("\r"); 01773 01774 /* Nun wird es spassig. 01775 01776 Eine SMS kann nicht, wie _alle_ anderen Befehle, mit einem einzelnen Kommando verschickt werden. 01777 Nach Abschicken des obrigen Befehls antwortet das Telefon mit folgendem Prompt "> ". 01778 In diesem Prompt kann die PDU an das Telefon übergeben werden kann. 01779 Die Sequenz wird mit CTRL-Z (\x1a) abgeschlossen. 01780 Noch was zu CTRL-Z, dies bedeutete unter DOS EOF. Der GSM Standard wurde 1994/95 entwickelt. 01781 Der Entwickler scheint DOS benutzt zu haben. 01782 01783 An dieser Stelle nochmal einen herzlichen Dank an den Entwickler von ezV24. 01784 Ich wuesste nicht, wie ich ohne seine Lib mit diesem Telephon haette plaudern koennen. 01785 Mir kommt z.B. spontan Software Flow Control (XON/XOFF) in den Sinn... */ 01786 01787 01788 /* Diese Methode ist im Gesamten etwas speziell, deshalb werden die folgenden drei Variablen, 01789 der Uebersicht halber, gleich hier deklariert. */ 01790 bool prompt = false; 01791 int stop = 0; 01792 char buffer[512]; 01793 01794 /* Teile dem Telephon mit, das BluePhone eine PDU codierte SMS senden moechte. */ 01795 v24Puts(m_Port, m_AtCommand.latin1()); 01796 while(!stop) 01797 { 01798 v24Gets(m_Port, buffer, 512); 01799 if (strstr(buffer, ">")) 01800 { 01801 stop = 1; 01802 prompt = true; 01803 } 01804 else if (strstr(buffer, "ERROR")) 01805 { 01806 stop = 1; 01807 QMessageBox::critical( this, 01808 tr("Error"), 01809 tr("Phone is unhappy.\n\nPlease quit BluePhone, reboot your phone and try again.\nThis is not a joke." ) 01810 ); 01811 } 01812 } 01813 01814 /* Falls wir den Prompt haben, uebermittle die PDU */ 01815 if (prompt) 01816 { 01817 v24Puts(m_Port, m_PDU.latin1()); 01818 v24Puts(m_Port, "\x1a"); 01819 v24Gets(m_Port, buffer, 512); 01820 v24Gets(m_Port, buffer, 512); 01821 01822 if (strstr(buffer, "ERROR")) 01823 { 01824 QMessageBox::critical( this, 01825 tr("Error"), 01826 tr("Phone is unhappy.\n\nPlease quit BluePhone, reboot your phone and try again.\nThis is not a joke." ) 01827 ); 01828 } 01829 else 01830 { 01831 QMessageBox::information( this, 01832 tr("Information"), 01833 tr("SMS successfully sent." ) 01834 ); 01835 } 01836 } 01837 else 01838 { 01839 QMessageBox::critical( this, 01840 tr("Error"), 01841 tr("Phone does not answer.\n\nPlease quit BluePhone, reboot your phone and try again.\nThis is not a joke." ) 01842 ); 01843 } 01844 } 01845 01846 01847 #include "bluephone.moc" 01848

Generated on Tue Aug 17 14:42:26 2004 for BluePhone by doxygen 1.3.7